commit 4c3523d2138ddcaabb2cd80058ce0259d17735e1
Author: Nathaniel McCallum <npmccallum(a)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]));