From 44ee4199e7ceb2a2c3df8cff6bc47a15b6317899 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Fri, 26 Jun 2015 16:21:27 +1000 Subject: [PATCH 1/4] src/cqueues: Add cq:pollset method It returns 3 tables of file descriptors that need to be polled for POLLIN, POLLOUT and POLLPRI respectively --- src/cqueues.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/cqueues.c b/src/cqueues.c index d452640..9b43475 100644 --- a/src/cqueues.c +++ b/src/cqueues.c @@ -2466,6 +2466,31 @@ static int cqueue_reset(lua_State *L) { } /* cqueue_reset() */ +static int cqueue_pollset(lua_State *L) { + struct cqueue *Q = cqueue_checkself(L, 1); + struct fileno *fileno; + lua_Integer r=0, w=0, p=0; + lua_newtable(L); /* POLLIN */ + lua_newtable(L); /* POLLOUT */ + lua_newtable(L); /* POLLPRI */ + LIST_FOREACH(fileno, &Q->fileno.polling, le) { + if (fileno->state & POLLIN) { + lua_pushinteger(L, fileno->fd); + lua_rawseti(L, -4, ++r); + } + if (fileno->state & POLLOUT) { + lua_pushinteger(L, fileno->fd); + lua_rawseti(L, -3, ++w); + } + if (fileno->state & POLLPRI) { + lua_pushinteger(L, fileno->fd); + lua_rawseti(L, -2, ++p); + } + } + return 3; +} /* cqueue_pollset() */ + + cqs_error_t cqs_sigmask(int how, const sigset_t *set, sigset_t *oset) { if (oset) sigemptyset(oset); @@ -2885,6 +2910,7 @@ static const luaL_Reg cqueue_methods[] = { { "pollfd", &cqueue_pollfd }, { "events", &cqueue_events }, { "timeout", &cqueue_timeout }, + { "pollset", &cqueue_pollset }, { "close", &cqueue_close }, { NULL, NULL } }; /* cqueue_methods[] */ From ea2879e457c9f2c2344a6aa901c681599572e24c Mon Sep 17 00:00:00 2001 From: daurnimator Date: Sat, 3 Jun 2017 19:20:33 +1000 Subject: [PATCH 2/4] src/cqueues.c: Add .n fields to pollset tables --- src/cqueues.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/cqueues.c b/src/cqueues.c index 9b43475..c960557 100644 --- a/src/cqueues.c +++ b/src/cqueues.c @@ -2487,6 +2487,14 @@ static int cqueue_pollset(lua_State *L) { lua_rawseti(L, -2, ++p); } } + + lua_pushinteger(L, r); + lua_setfield(L, -4, "n"); + lua_pushinteger(L, w); + lua_setfield(L, -3, "n"); + lua_pushinteger(L, p); + lua_setfield(L, -2, "n"); + return 3; } /* cqueue_pollset() */ From f9db3cb04cf723c3211632143f7e7edb5d3db387 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Sat, 3 Jun 2017 22:29:30 +1000 Subject: [PATCH 3/4] regress/185-pollset.lua: Add test case for :pollset() --- regress/185-pollset.lua | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100755 regress/185-pollset.lua diff --git a/regress/185-pollset.lua b/regress/185-pollset.lua new file mode 100755 index 0000000..24b3212 --- /dev/null +++ b/regress/185-pollset.lua @@ -0,0 +1,36 @@ +#!/bin/sh +_=[[ + . "${0%%/*}/regress.sh" + exec runlua "$0" "$@" +]] +require"regress".export".*" + +local cq = cqueues.new() +local rd, wr = check(socket.pair()) +local pre_poll = false +local post_poll = false +cq:wrap(function() + pre_poll = true + cqueues.poll({ + pollfd = rd:pollfd(); + events = "r"; + }) + post_poll = true +end) +assert(cq:step(0)) +check(pre_poll and not post_poll) + +local r, w, p = cq:pollset() +check(r.n == 1 and r[1] == rd:pollfd(), "read set doesn't contain expected values") +check(w.n == 0, "write set doesn't contain expected values") +check(p.n == 0, "priority set doesn't contain expected values") + +assert(cq:step(0)) +check(not post_poll, "Thread was unexpectedly advanced") + +cqueues.cancel(rd) +assert(cq:step(0)) + +check(post_poll, "Thread wasn't advanced") + +say("OK") From 0e03e53b5798a52b5ca7f2977fda25b6243e325b Mon Sep 17 00:00:00 2001 From: daurnimator Date: Sat, 3 Jun 2017 23:56:20 +1000 Subject: [PATCH 4/4] src/cqueues.c: :pollset should also return fd woken by conditions --- regress/185-pollset.lua | 2 +- src/cqueues.c | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/regress/185-pollset.lua b/regress/185-pollset.lua index 24b3212..f862076 100755 --- a/regress/185-pollset.lua +++ b/regress/185-pollset.lua @@ -21,7 +21,7 @@ assert(cq:step(0)) check(pre_poll and not post_poll) local r, w, p = cq:pollset() -check(r.n == 1 and r[1] == rd:pollfd(), "read set doesn't contain expected values") +check(r.n == 1 and r[2] == rd:pollfd(), "read set doesn't contain expected values") check(w.n == 0, "write set doesn't contain expected values") check(p.n == 0, "priority set doesn't contain expected values") diff --git a/src/cqueues.c b/src/cqueues.c index c960557..fda6d7c 100644 --- a/src/cqueues.c +++ b/src/cqueues.c @@ -519,6 +519,14 @@ static int alert_rearm(struct kpoll *kp) { #endif } /* alert_rearm() */ +static int alert_pollfd(struct kpoll *kp) { +#if ENABLE_PORTS + return kp->fd; +#else + return kp->alert.fd[0]; +#endif +} /* alert_pollfd() */ + static int kpoll_init(struct kpoll *kp) { int error; @@ -2473,6 +2481,11 @@ static int cqueue_pollset(lua_State *L) { lua_newtable(L); /* POLLIN */ lua_newtable(L); /* POLLOUT */ lua_newtable(L); /* POLLPRI */ + + /* the fd woken by conditions */ + lua_pushinteger(L, alert_pollfd(&Q->kp)); + lua_rawseti(L, -4, ++r); + LIST_FOREACH(fileno, &Q->fileno.polling, le) { if (fileno->state & POLLIN) { lua_pushinteger(L, fileno->fd);