commit 4c3523d2138ddcaabb2cd80058ce0259d17735e1 Author: Nathaniel McCallum npmccallum@redhat.com Date: Thu Nov 17 14:03:34 2011 -0500
[core] add verto_get_fd_state() and verto_set_fd_state(); enable backends to report fd state
src/verto-glib.c | 10 ++++++++++ src/verto-libev.c | 12 +++++++++++- src/verto-libevent.c | 12 ++++++++++++ src/verto-module.h | 15 +++++++++++++++ src/verto-tevent.c | 40 ++++++++++++++++++++++++++++++---------- src/verto.c | 38 +++++++++++++++++++++++++++++++++++--- src/verto.h | 13 ++++++++++++- tests/abi | 2 +- tests/read.c | 3 +++ tests/write.c | 3 +++ 10 files changed, 132 insertions(+), 16 deletions(-) --- diff --git a/src/verto-glib.c b/src/verto-glib.c index ac00314..c78e01b 100644 --- a/src/verto-glib.c +++ b/src/verto-glib.c @@ -142,6 +142,16 @@ glib_callback(gpointer data) static gboolean glib_callback_io(GIOChannel *source, GIOCondition condition, gpointer data) { + verto_ev_flag state = VERTO_EV_FLAG_NONE; + + if (condition & (G_IO_IN | G_IO_PRI)) + state |= VERTO_EV_FLAG_IO_READ; + if (condition & G_IO_OUT) + state |= VERTO_EV_FLAG_IO_WRITE; + if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) + state |= VERTO_EV_FLAG_IO_ERROR; + + verto_set_fd_state(data, state); return glib_callback(data); }
diff --git a/src/verto-libev.c b/src/verto-libev.c index 4e6e816..deb021e 100644 --- a/src/verto-libev.c +++ b/src/verto-libev.c @@ -78,9 +78,19 @@ libev_ctx_reinitialize(verto_mod_ctx *ctx) static void libev_callback(EV_P_ ev_watcher *w, int revents) { - if (verto_get_type(w->data) == VERTO_EV_TYPE_CHILD) + verto_ev_flag state = VERTO_EV_FLAG_NONE; + + if (verto_get_type(w->data)== VERTO_EV_TYPE_CHILD) verto_set_proc_status(w->data, ((ev_child*) w)->rstatus);
+ if (revents & EV_READ) + state |= VERTO_EV_FLAG_IO_READ; + if (revents & EV_WRITE) + state |= VERTO_EV_FLAG_IO_WRITE; + if (revents & EV_ERROR) + state |= VERTO_EV_FLAG_IO_ERROR; + + verto_set_fd_state(w->data, state); verto_fire(w->data); }
diff --git a/src/verto-libevent.c b/src/verto-libevent.c index 80fb00d..031ea00 100644 --- a/src/verto-libevent.c +++ b/src/verto-libevent.c @@ -92,6 +92,18 @@ libevent_ctx_reinitialize(verto_mod_ctx *ctx) static void libevent_callback(evutil_socket_t socket, short type, void *data) { + verto_ev_flag state = VERTO_EV_FLAG_NONE; + + if (type & EV_READ) + state |= VERTO_EV_FLAG_IO_READ; + if (type & EV_WRITE) + state |= VERTO_EV_FLAG_IO_WRITE; +#ifdef EV_ERROR + if (type & EV_ERROR) + state |= VERTO_EV_FLAG_IO_ERROR; +#endif + + verto_set_fd_state(data, state); verto_fire(data); }
diff --git a/src/verto-module.h b/src/verto-module.h index b0e7232..630a4bf 100644 --- a/src/verto-module.h +++ b/src/verto-module.h @@ -166,4 +166,19 @@ verto_fire(verto_ev *ev); void verto_set_proc_status(verto_ev *ev, verto_proc_status status);
+/** + * Sets the state of the fd which caused this event to fire. + * + * This function does nothing if the verto_ev is not a io type. + * + * Only the flags VERTO_EV_FLAG_IO_(READ|WRITE|ERROR) are supported. All other + * flags are unset. + * + * @see verto_add_io() + * @param ev The verto_ev to set the state in. + * @param state The fd state. + */ +void +verto_set_fd_state(verto_ev *ev, verto_ev_flag state); + #endif /* VERTO_MODULE_H_ */ diff --git a/src/verto-tevent.c b/src/verto-tevent.c index c4c363d..f91b9a4 100644 --- a/src/verto-tevent.c +++ b/src/verto-tevent.c @@ -61,16 +61,36 @@ tevent_ctx_reinitialize(verto_mod_ctx *ctx) tevent_re_initialise(ctx); }
-#define definecb(type, ...) \ - static void tevent_ ## type ## _cb(struct tevent_context *c, \ - struct tevent_ ## type *e, \ - __VA_ARGS__, void *data) { \ - verto_fire(data); \ - } +static void +tevent_fd_cb(struct tevent_context *c, struct tevent_fd *e, + uint16_t fl, void *data) +{ + verto_ev_flag state = VERTO_EV_FLAG_NONE; + + if (fl & TEVENT_FD_READ) + state |= VERTO_EV_FLAG_IO_READ; + if (fl & TEVENT_FD_WRITE) + state |= VERTO_EV_FLAG_IO_WRITE; + if (fl & TEVENT_FD_ERROR) + state |= VERTO_EV_FLAG_IO_ERROR;
-definecb(fd, uint16_t fl) -definecb(timer, struct timeval ct) -definecb(signal, int signum, int count, void *siginfo) + verto_set_fd_state(data, state); + verto_fire(data); +} + +static void +tevent_timer_cb(struct tevent_context *c, struct tevent_timer *e, + struct timeval ct, void *data) +{ + verto_fire(data); +} + +static void +tevent_signal_cb(struct tevent_context *c, struct tevent_signal *e, + int signum, int count, void *siginfo, void *data) +{ + verto_fire(data); +}
static verto_mod_ev * tevent_ctx_add(verto_mod_ctx *ctx, const verto_ev *ev, verto_ev_flag *flags) diff --git a/src/verto.c b/src/verto.c index bf72e9c..d84d8cb 100644 --- a/src/verto.c +++ b/src/verto.c @@ -59,6 +59,11 @@ typedef struct { verto_proc_status status; } verto_child;
+typedef struct { + int fd; + verto_ev_flag state; +} verto_io; + struct verto_ev { verto_ev *next; verto_ctx *ctx; @@ -72,7 +77,7 @@ struct verto_ev { size_t depth; int deleted; union { - int fd; + verto_io io; int signal; time_t interval; verto_child child; @@ -625,7 +630,7 @@ verto_add_io(verto_ctx *ctx, verto_ev_flag flags, if (fd < 0 || !(flags & (VERTO_EV_FLAG_IO_READ | VERTO_EV_FLAG_IO_WRITE))) return NULL;
- doadd(ev, ev->option.fd = fd, VERTO_EV_TYPE_IO); + doadd(ev, ev->option.io.fd = fd, VERTO_EV_TYPE_IO); return ev; }
@@ -719,10 +724,16 @@ int verto_get_fd(const verto_ev *ev) { if (ev && (ev->type == VERTO_EV_TYPE_IO)) - return ev->option.fd; + return ev->option.io.fd; return -1; }
+verto_ev_flag +verto_get_fd_state(const verto_ev *ev) +{ + return ev->option.io.state; +} + time_t verto_get_interval(const verto_ev *ev) { @@ -885,6 +896,11 @@ verto_fire(verto_ev *ev) ev->ctx->module->funcs->ctx_del(ev->ctx->ctx, ev, ev->ev); ev->ev = priv; } + + if (ev->type == VERTO_EV_TYPE_IO) + ev->option.io.state = VERTO_EV_FLAG_NONE; + if (ev->type == VERTO_EV_TYPE_CHILD) + ev->option.child.status = 0; } }
@@ -894,3 +910,19 @@ verto_set_proc_status(verto_ev *ev, verto_proc_status status) if (ev && ev->type == VERTO_EV_TYPE_CHILD) ev->option.child.status = status; } + +void +verto_set_fd_state(verto_ev *ev, verto_ev_flag state) +{ + /* Filter out only the io flags */ + state = state & (VERTO_EV_FLAG_IO_READ | + VERTO_EV_FLAG_IO_WRITE | + VERTO_EV_FLAG_IO_ERROR); + + /* Don't report read/write if the socket is closed */ + if (state & VERTO_EV_FLAG_IO_ERROR) + state = VERTO_EV_FLAG_IO_ERROR; + + if (ev && ev->type == VERTO_EV_TYPE_IO) + ev->option.io.state = state; +} diff --git a/src/verto.h b/src/verto.h index c659c2e..91fa720 100644 --- a/src/verto.h +++ b/src/verto.h @@ -64,8 +64,9 @@ typedef enum { VERTO_EV_FLAG_PRIORITY_HIGH = 1 << 3, VERTO_EV_FLAG_IO_READ = 1 << 4, VERTO_EV_FLAG_IO_WRITE = 1 << 5, + VERTO_EV_FLAG_IO_ERROR = 1 << 7, VERTO_EV_FLAG_REINITIABLE = 1 << 6, - _VERTO_EV_FLAG_MAX = VERTO_EV_FLAG_REINITIABLE + _VERTO_EV_FLAG_MAX = VERTO_EV_FLAG_IO_ERROR } verto_ev_flag;
typedef void (verto_callback)(verto_ctx *ctx, verto_ev *ev); @@ -441,6 +442,16 @@ int verto_get_fd(const verto_ev *ev);
/** + * Gets the file descriptor state from when the event fires. + * + * @see verto_add_io() + * @param ev The verto_ev to retrieve the fd state from. + * @return The fd state. + */ +verto_ev_flag +verto_get_fd_state(const verto_ev *ev); + +/** * Gets the interval associated with a timeout verto_ev. * * @see verto_add_timeout() diff --git a/tests/abi b/tests/abi index cbbdf26..20464cd 100755 --- a/tests/abi +++ b/tests/abi @@ -13,4 +13,4 @@ fi
HASH=`nm -g $LIBVERTO | awk '/^[0-9a-fA-F]+ T verto_/ { print $NF; }' | sed 's|^_||' | sort -u | $HASHCMD | cut -d' ' -f1` echo "Hash: $HASH" -test $HASH = af68235ae7f8f577dc37536ce1534688 +test $HASH = 04d2af279a5cf456a37cdd4aece75ff0 diff --git a/tests/read.c b/tests/read.c index 0d32084..9d0bca5 100644 --- a/tests/read.c +++ b/tests/read.c @@ -63,11 +63,14 @@ cb(verto_ctx *ctx, verto_ev *ev)
bytes = read(fd, buff, DATALEN); if (callcount++ == 0) { + assert(verto_get_fd_state(ev) & VERTO_EV_FLAG_IO_READ); assert(bytes == DATALEN); close(fds[1]); fds[1] = -1; } else { + if (!(verto_get_fd_state(ev) & VERTO_EV_FLAG_IO_ERROR)) + printf("WARNING: VERTO_EV_FLAG_IO_ERROR not supported!\n"); assert(bytes != DATALEN); close(fd); fds[0] = -1; diff --git a/tests/write.c b/tests/write.c index 97b00e3..0a2422c 100644 --- a/tests/write.c +++ b/tests/write.c @@ -58,6 +58,8 @@ error_cb(verto_ctx *ctx, verto_ev *ev)
/* When we get here, the fd should be closed, so an error should occur */ fd = verto_get_fd(ev); + if (!(verto_get_fd_state(ev) & VERTO_EV_FLAG_IO_ERROR)) + printf("WARNING: VERTO_EV_FLAG_IO_ERROR not supported!\n"); assert(write(fd, DATA, DATALEN) != DATALEN); close(fd); fds[1] = -1; @@ -83,6 +85,7 @@ write_cb(verto_ctx *ctx, verto_ev *ev) int fd = 0;
fd = verto_get_fd(ev); + assert(verto_get_fd_state(ev) & VERTO_EV_FLAG_IO_WRITE); assert(write(fd, DATA, DATALEN) == DATALEN);
assert(verto_add_io(ctx, VERTO_EV_FLAG_IO_READ, read_cb, fds[0]));
libverto-commits@lists.fedorahosted.org