commit d75df28b497fb540b2a6ed8f9a4854e7814dc95f
Author: Nathaniel McCallum <npmccallum(a)redhat.com>
Date: Wed Jun 29 11:47:08 2011 -0400
[all] add a persistence flag; remove verto_repeat()
src/verto-glib.c | 12 +++++---
src/verto-libev.c | 4 ++-
src/verto-libevent.c | 13 ++++++---
src/verto-module.h | 4 ++-
src/verto-tevent.c | 4 ++-
src/verto.c | 72 ++++++++++++++++++++++++++-----------------------
src/verto.h | 46 ++++++++++++++-----------------
tests/child.c | 7 +++-
tests/idle.c | 43 +++++++++++++++++++----------
tests/read.c | 4 +-
tests/signal.c | 8 +++---
tests/test.h | 13 +++++++++
tests/timeout.c | 57 +++++++++++++++++++++++----------------
tests/write.c | 10 +++---
14 files changed, 174 insertions(+), 123 deletions(-)
---
diff --git a/src/verto-glib.c b/src/verto-glib.c
index a8d652b..5104c4c 100644
--- a/src/verto-glib.c
+++ b/src/verto-glib.c
@@ -99,16 +99,15 @@ glib_ctx_break(void *lp)
static gboolean
glib_callback(gpointer data)
{
- gboolean retval = verto_get_type(data) == VERTO_EV_TYPE_SIGNAL;
+ gboolean persists = verto_get_flags(data) & VERTO_EV_FLAG_PERSIST;
verto_fire(data);
- return retval;
+ return persists;
}
gboolean
glib_callback_io(GIOChannel *source, GIOCondition condition, gpointer data)
{
- verto_fire(data);
- return TRUE;
+ return glib_callback(data);
}
static void
@@ -119,11 +118,13 @@ glib_callback_child(GPid pid, gint status, gpointer data)
}
static void *
-glib_ctx_add(void *ctx, const struct vertoEv *ev)
+glib_ctx_add(void *ctx, const struct vertoEv *ev, bool *persists)
{
struct glibEv *gev = NULL;
enum vertoEvType type = verto_get_type(ev);
+ *persists = verto_get_flags(ev) & VERTO_EV_FLAG_PERSIST;
+
gev = g_new0(struct glibEv, 1);
if (!gev)
return NULL;
@@ -150,6 +151,7 @@ glib_ctx_add(void *ctx, const struct vertoEv *ev)
break;
case VERTO_EV_TYPE_CHILD:
gev->src = g_child_watch_source_new(verto_get_pid(ev));
+ *persists = false;
break;
case VERTO_EV_TYPE_SIGNAL:
#if GLIB_MAJOR_VERSION >= 2
diff --git a/src/verto-libev.c b/src/verto-libev.c
index a59fe8b..1409033 100644
--- a/src/verto-libev.c
+++ b/src/verto-libev.c
@@ -73,7 +73,7 @@ libev_callback(EV_P_ ev_watcher *w, int revents)
return type ## w
static void *
-libev_ctx_add(void *ctx, const struct vertoEv *ev)
+libev_ctx_add(void *ctx, const struct vertoEv *ev, bool *persists)
{
ev_io *iow = NULL;
ev_timer *timerw = NULL;
@@ -83,6 +83,7 @@ libev_ctx_add(void *ctx, const struct vertoEv *ev)
ev_tstamp interval;
int events = EV_NONE;
+ *persists = true;
switch (verto_get_type(ev)) {
case VERTO_EV_TYPE_IO:
if (verto_get_io_flags(ev) & VERTO_EV_IO_FLAG_READ)
@@ -98,6 +99,7 @@ libev_ctx_add(void *ctx, const struct vertoEv *ev)
case VERTO_EV_TYPE_SIGNAL:
setuptype(signal, ev, libev_callback, verto_get_signal(ev));
case VERTO_EV_TYPE_CHILD:
+ *persists = false;
setuptype(child, ev, libev_callback, verto_get_pid(ev), 0);
default:
return NULL; /* Not supported */
diff --git a/src/verto-libevent.c b/src/verto-libevent.c
index 30f41d2..983c95b 100644
--- a/src/verto-libevent.c
+++ b/src/verto-libevent.c
@@ -71,12 +71,16 @@ libevent_callback(evutil_socket_t socket, short type, void *data)
}
static void *
-libevent_ctx_add(void *ctx, const struct vertoEv *ev)
+libevent_ctx_add(void *ctx, const struct vertoEv *ev, bool *persists)
{
struct event *priv = NULL;
struct timeval *timeout = NULL;
struct timeval tv;
- int flags = EV_PERSIST;
+ int flags = 0;
+
+ *persists = verto_get_flags(ev) & VERTO_EV_FLAG_PERSIST;
+ if (*persists)
+ flags |= EV_PERSIST;
switch (verto_get_type(ev)) {
case VERTO_EV_TYPE_IO:
@@ -91,10 +95,11 @@ libevent_ctx_add(void *ctx, const struct vertoEv *ev)
timeout = &tv;
tv.tv_sec = verto_get_interval(ev) / 1000;
tv.tv_usec = verto_get_interval(ev) % 1000 * 1000;
- priv = event_new(ctx, -1, EV_TIMEOUT, libevent_callback, (void *) ev);
+ priv = event_new(ctx, -1, EV_TIMEOUT | flags, libevent_callback,
+ (void *) ev);
break;
case VERTO_EV_TYPE_SIGNAL:
- priv = event_new(ctx, verto_get_signal(ev), EV_SIGNAL | EV_PERSIST,
+ priv = event_new(ctx, verto_get_signal(ev), EV_SIGNAL | flags,
libevent_callback, (void *) ev);
break;
case VERTO_EV_TYPE_IDLE:
diff --git a/src/verto-module.h b/src/verto-module.h
index 9bc0d6c..bbfeaa3 100644
--- a/src/verto-module.h
+++ b/src/verto-module.h
@@ -27,6 +27,8 @@
#ifndef VERTO_MODULE_H_
#define VERTO_MODULE_H_
+#include <stdbool.h>
+
#include <verto.h>
#define VERTO_MODULE_VERSION 1
@@ -63,7 +65,7 @@ struct vertoEvCtxFuncs {
void (*ctx_run)(void *ctx);
void (*ctx_run_once)(void *ctx);
void (*ctx_break)(void *ctx);
- void *(*ctx_add)(void *ctx, const struct vertoEv *ev);
+ void *(*ctx_add)(void *ctx, const struct vertoEv *ev, bool *persists);
void (*ctx_del)(void *ctx, const struct vertoEv *ev, void *evpriv);
};
diff --git a/src/verto-tevent.c b/src/verto-tevent.c
index 307ed6f..c605955 100644
--- a/src/verto-tevent.c
+++ b/src/verto-tevent.c
@@ -78,12 +78,13 @@ definecb(timer, struct timeval ct)
definecb(signal, int signum, int count, void *siginfo)
static void *
-tevent_ctx_add(void *ctx, const struct vertoEv *ev)
+tevent_ctx_add(void *ctx, const struct vertoEv *ev, bool *persists)
{
time_t interval;
struct timeval tv;
uint16_t flags = 0;
+ *persists = true;
switch (verto_get_type(ev)) {
case VERTO_EV_TYPE_IO:
if (verto_get_io_flags(ev) & VERTO_EV_IO_FLAG_READ)
@@ -93,6 +94,7 @@ tevent_ctx_add(void *ctx, const struct vertoEv *ev)
return tevent_add_fd(tctx(ctx), tctx(ctx), verto_get_io_fd(ev),
flags, tevent_fd_cb, (void *) ev);
case VERTO_EV_TYPE_TIMEOUT:
+ *persists = false;
interval = verto_get_interval(ev);
tv = tevent_timeval_current_ofs(interval / 1000, interval % 1000 * 1000);
return tevent_add_timer(tctx(ctx), tctx(ctx), tv,
diff --git a/src/verto.c b/src/verto.c
index 3ec30af..9221487 100644
--- a/src/verto.c
+++ b/src/verto.c
@@ -24,11 +24,11 @@
#define _GNU_SOURCE /* For dladdr(), asprintf() */
-#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
+#include <assert.h>
#include <libgen.h>
#include <sys/types.h>
@@ -56,7 +56,7 @@ struct vertoChild {
struct vertoIO {
int fd;
- enum vertoEvIOFlags flags;
+ enum vertoEvIOFlag flags;
};
struct vertoEv {
@@ -67,6 +67,8 @@ struct vertoEv {
vertoCallback callback;
void *priv;
void *modpriv;
+ enum vertoEvFlag flags;
+ bool persists;
union {
int signal;
time_t interval;
@@ -221,7 +223,8 @@ load_module(const char *impl, void **dll, const struct vertoModule **module)
static inline struct vertoEv *
make_ev(struct vertoEvCtx *ctx, enum vertoEvPriority priority,
- vertoCallback callback, void *priv, enum vertoEvType type)
+ vertoCallback callback, void *priv, enum vertoEvType type,
+ enum vertoEvFlag flags)
{
struct vertoEv *ev = NULL;
@@ -240,6 +243,7 @@ make_ev(struct vertoEvCtx *ctx, enum vertoEvPriority priority,
ev->priority = priority;
ev->callback = callback;
ev->priv = priv;
+ ev->flags = flags;
}
return ev;
@@ -393,10 +397,10 @@ verto_break(struct vertoEvCtx *ctx)
}
#define doadd(set, type) \
- struct vertoEv *ev = make_ev(ctx, priority, callback, priv, type); \
+ struct vertoEv *ev = make_ev(ctx, priority, callback, priv, type, flags); \
if (ev) { \
set; \
- ev->modpriv = ctx->funcs.ctx_add(ctx->modpriv, ev); \
+ ev->modpriv = ctx->funcs.ctx_add(ctx->modpriv, ev, &ev->persists); \
if (!ev->modpriv) { \
free(ev); \
return NULL; \
@@ -407,31 +411,35 @@ verto_break(struct vertoEvCtx *ctx)
struct vertoEv *
verto_add_io(struct vertoEvCtx *ctx, enum vertoEvPriority priority,
- vertoCallback callback, void *priv, int fd,
- enum vertoEvIOFlags flags)
+ enum vertoEvFlag flags, vertoCallback callback, void *priv, int fd,
+ enum vertoEvIOFlag ioflags)
{
if (fd < 0)
return NULL;
- doadd(ev->option.io.fd = fd; ev->option.io.flags = flags, VERTO_EV_TYPE_IO);
+ doadd(ev->option.io.fd = fd;
+ ev->option.io.flags = ioflags,
+ VERTO_EV_TYPE_IO);
}
struct vertoEv *
verto_add_timeout(struct vertoEvCtx *ctx, enum vertoEvPriority priority,
- vertoCallback callback, void *priv, time_t interval)
+ enum vertoEvFlag flags, vertoCallback callback, void *priv,
+ time_t interval)
{
doadd(ev->option.interval = interval, VERTO_EV_TYPE_TIMEOUT);
}
struct vertoEv *
verto_add_idle(struct vertoEvCtx *ctx, enum vertoEvPriority priority,
- vertoCallback callback, void *priv)
+ enum vertoEvFlag flags, vertoCallback callback, void *priv)
{
doadd(, VERTO_EV_TYPE_IDLE);
}
struct vertoEv *
verto_add_signal(struct vertoEvCtx *ctx, enum vertoEvPriority priority,
- vertoCallback callback, void *priv, int signal)
+ enum vertoEvFlag flags, vertoCallback callback, void *priv,
+ int signal)
{
if (signal < 0 || signal == SIGCHLD)
return NULL;
@@ -442,32 +450,14 @@ verto_add_signal(struct vertoEvCtx *ctx, enum vertoEvPriority priority,
struct vertoEv *
verto_add_child(struct vertoEvCtx *ctx, enum vertoEvPriority priority,
- vertoCallback callback, void *priv, pid_t pid)
+ enum vertoEvFlag flags, vertoCallback callback, void *priv,
+ pid_t pid)
{
- if (pid < 1)
+ if (pid < 1 || (flags & VERTO_EV_FLAG_PERSIST)) /* persist makes no sense */
return NULL;
doadd(ev->option.child.pid = pid, VERTO_EV_TYPE_CHILD);
}
-struct vertoEv *
-verto_repeat(const struct vertoEv *ev)
-{
- switch (ev->type) {
- case VERTO_EV_TYPE_TIMEOUT:
- return verto_add_timeout(ev->ctx, ev->priority, ev->callback, ev->priv,
- ev->option.interval);
- case VERTO_EV_TYPE_IDLE:
- return verto_add_idle(ev->ctx, ev->priority, ev->callback, ev->priv);
- case VERTO_EV_TYPE_CHILD:
- case VERTO_EV_TYPE_IO:
- case VERTO_EV_TYPE_SIGNAL:
- default:
- break; /* Not supported */
- }
-
- return NULL;
-}
-
void *
verto_get_private(const struct vertoEv *ev)
{
@@ -486,6 +476,12 @@ verto_get_priority(const struct vertoEv *ev)
return ev->priority;
}
+enum vertoEvFlag
+verto_get_flags(const struct vertoEv *ev)
+{
+ return ev->flags;
+}
+
int
verto_get_io_fd(const struct vertoEv *ev)
{
@@ -494,7 +490,7 @@ verto_get_io_fd(const struct vertoEv *ev)
return -1;
}
-enum vertoEvIOFlags
+enum vertoEvIOFlag
verto_get_io_flags(const struct vertoEv *ev)
{
if (ev && (ev->type & VERTO_EV_TYPE_IO))
@@ -569,9 +565,17 @@ verto_convert_funcs(const struct vertoEvCtxFuncs *funcs,
void
verto_fire(struct vertoEv *ev)
{
+ void *priv;
+
ev->callback(ev->ctx, ev);
- if (!(ev->type & (VERTO_EV_TYPE_SIGNAL | VERTO_EV_TYPE_IO)))
+ if (!(ev->flags & VERTO_EV_FLAG_PERSIST))
verto_del(ev);
+ else if (!ev->persists) {
+ priv = ev->ctx->funcs.ctx_add(ev->ctx->modpriv, ev, &ev->persists);
+ assert(priv); /* TODO: create an error callback */
+ ev->ctx->funcs.ctx_del(ev->ctx->modpriv, ev, ev->modpriv);
+ ev->modpriv = priv;
+ }
}
void
diff --git a/src/verto.h b/src/verto.h
index 4f93ad4..a77bcee 100644
--- a/src/verto.h
+++ b/src/verto.h
@@ -50,10 +50,17 @@ enum vertoEvPriority {
_VERTO_EV_PRIORITY_MAX = VERTO_EV_PRIORITY_HIGH
};
-enum vertoEvIOFlags {
+enum vertoEvFlag {
+ VERTO_EV_FLAG_NONE = 0,
+ VERTO_EV_FLAG_PERSIST = 1,
+ _VERTO_EV_FLAG_MAX = VERTO_EV_FLAG_PERSIST
+};
+
+enum vertoEvIOFlag {
VERTO_EV_IO_FLAG_NONE = 0,
VERTO_EV_IO_FLAG_READ = 1,
VERTO_EV_IO_FLAG_WRITE = 1 << 1,
+ _VERTO_EV_IO_FLAG_MAX = VERTO_EV_IO_FLAG_WRITE
};
typedef void (*vertoCallback)(struct vertoEvCtx *ctx, struct vertoEv *ev);
@@ -207,8 +214,8 @@ verto_break(struct vertoEvCtx *ctx);
*/
struct vertoEv *
verto_add_io(struct vertoEvCtx *ctx, enum vertoEvPriority priority,
- vertoCallback callback, void *priv, int fd,
- enum vertoEvIOFlags flags);
+ enum vertoEvFlag flags, vertoCallback callback, void *priv, int fd,
+ enum vertoEvIOFlag ioflags);
/**
* Adds a callback executed after a period of time.
@@ -234,7 +241,8 @@ verto_add_io(struct vertoEvCtx *ctx, enum vertoEvPriority priority,
*/
struct vertoEv *
verto_add_timeout(struct vertoEvCtx *ctx, enum vertoEvPriority priority,
- vertoCallback callback, void *priv, time_t interval);
+ enum vertoEvFlag flags, vertoCallback callback, void *priv,
+ time_t interval);
/**
* Adds a callback executed when there is nothing else to do.
@@ -259,7 +267,7 @@ verto_add_timeout(struct vertoEvCtx *ctx, enum vertoEvPriority priority,
*/
struct vertoEv *
verto_add_idle(struct vertoEvCtx *ctx, enum vertoEvPriority priority,
- vertoCallback callback, void *priv);
+ enum vertoEvFlag flags, vertoCallback callback, void *priv);
/**
* Adds a callback executed when a signal is received.
@@ -296,7 +304,8 @@ verto_add_idle(struct vertoEvCtx *ctx, enum vertoEvPriority priority,
*/
struct vertoEv *
verto_add_signal(struct vertoEvCtx *ctx, enum vertoEvPriority priority,
- vertoCallback callback, void *priv, int signal);
+ enum vertoEvFlag flags, vertoCallback callback, void *priv,
+ int signal);
/**
* Adds a callback executed when a child process exits.
@@ -322,24 +331,8 @@ verto_add_signal(struct vertoEvCtx *ctx, enum vertoEvPriority priority,
*/
struct vertoEv *
verto_add_child(struct vertoEvCtx *ctx, enum vertoEvPriority priority,
- vertoCallback callback, void *priv, pid_t pid);
-
-/**
- * Duplicates the current event so that it will be fired again.
- *
- * Always returns NULL for signal events since they are persistent.
- *
- * @see verto_add_read()
- * @see verto_add_write()
- * @see verto_add_timeout()
- * @see verto_add_idle()
- * @see verto_add_child()
- * @see verto_del()
- * @param ev The vertoEv to add.
- * @return The new vertoEv registered with the event context.
- */
-struct vertoEv *
-verto_repeat(const struct vertoEv *ev);
+ enum vertoEvFlag flags, vertoCallback callback, void *priv,
+ pid_t pid);
/**
* Gets the private pointer of the vertoEv.
@@ -386,6 +379,9 @@ verto_get_type(const struct vertoEv *ev);
enum vertoEvPriority
verto_get_priority(const struct vertoEv *ev);
+enum vertoEvFlag
+verto_get_flags(const struct vertoEv *ev);
+
/**
* Gets the file descriptor associated with a read/write vertoEv.
*
@@ -397,7 +393,7 @@ verto_get_priority(const struct vertoEv *ev);
int
verto_get_io_fd(const struct vertoEv *ev);
-enum vertoEvIOFlags
+enum vertoEvIOFlag
verto_get_io_flags(const struct vertoEv *ev);
/**
diff --git a/tests/child.c b/tests/child.c
index 0ed89d9..e527375 100644
--- a/tests/child.c
+++ b/tests/child.c
@@ -64,9 +64,12 @@ do_test(struct vertoEvCtx *ctx)
exit(EXITCODE);
}
- verto_add_timeout(ctx, VERTO_EV_PRIORITY_DEFAULT, exit_cb, NULL, 100);
+ verto_add_timeout(ctx, VERTO_EV_PRIORITY_DEFAULT, VERTO_EV_FLAG_NONE, exit_cb, NULL, 100);
- if (!verto_add_child(ctx, VERTO_EV_PRIORITY_DEFAULT, cb, NULL, pid)) {
+ /* Persist makes no sense for children events */
+ assert(!verto_add_child(ctx, VERTO_EV_PRIORITY_DEFAULT, VERTO_EV_FLAG_PERSIST, cb, NULL, pid));
+
+ if (!verto_add_child(ctx, VERTO_EV_PRIORITY_DEFAULT, VERTO_EV_FLAG_NONE, cb, NULL, pid)) {
printf("WARNING: Child not supported!\n");
usleep(100000);
waitpid(pid, &exitstatus, 0);
diff --git a/tests/idle.c b/tests/idle.c
index 94728a3..1a508e4 100644
--- a/tests/idle.c
+++ b/tests/idle.c
@@ -24,16 +24,30 @@
#include "test.h"
-static int occurrences;
+static int callcount;
+struct vertoEv *idle = NULL;
void
exit_cb(struct vertoEvCtx *ctx, struct vertoEv *ev)
{
- if (occurrences == 0)
- printf("WARNING: Idle not supported!\n");
- else if (occurrences > 1) {
- printf("ERROR: Idle must not recur!\n");
- retval = 1;
+ retval = 1;
+ switch (callcount) {
+ case 1:
+ printf("ERROR: Idle (persist) did not recur!\n");
+ break;
+ case 2:
+ printf("ERROR: Idle (non-persist) did not fire!\n");
+ break;
+ case 0:
+ if (idle) {
+ printf("ERROR: Idle (persist) did not fire!\n");
+ break;
+ }
+ printf("WARNING: Idle not supported!\n");
+ case 3:
+ retval = 0;
+ default:
+ break;
}
verto_break(ctx);
@@ -42,19 +56,18 @@ exit_cb(struct vertoEvCtx *ctx, struct vertoEv *ev)
void
cb(struct vertoEvCtx *ctx, struct vertoEv *ev)
{
- if (++occurrences > 1)
- exit_cb(ctx, ev);
-
- verto_add_timeout(ctx, VERTO_EV_PRIORITY_DEFAULT, exit_cb, NULL, 100);
+ if (++callcount == 2) {
+ verto_add_idle(ctx, VERTO_EV_PRIORITY_DEFAULT, VERTO_EV_FLAG_NONE, cb, NULL);
+ verto_del(ev);
+ }
}
int
do_test(struct vertoEvCtx *ctx)
{
- occurrences = 0;
-
- if (!verto_add_idle(ctx, VERTO_EV_PRIORITY_DEFAULT, cb, NULL))
- verto_add_timeout(ctx, VERTO_EV_PRIORITY_DEFAULT, exit_cb, NULL, 1);
-
+ callcount = 0;
+ idle = verto_add_idle(ctx, VERTO_EV_PRIORITY_DEFAULT, VERTO_EV_FLAG_PERSIST, cb, NULL);
+ assert(verto_add_timeout(ctx, VERTO_EV_PRIORITY_DEFAULT, VERTO_EV_FLAG_NONE,
+ exit_cb, NULL, idle ? 100 : 1));
return 0;
}
diff --git a/tests/read.c b/tests/read.c
index 056e236..d769d65 100644
--- a/tests/read.c
+++ b/tests/read.c
@@ -83,8 +83,8 @@ do_test(struct vertoEvCtx *ctx)
fds[1] = -1;
assert(pipe(fds) == 0);
- assert(verto_add_timeout(ctx, VERTO_EV_PRIORITY_DEFAULT, timeout_cb, NULL, 1000));
- assert(verto_add_io(ctx, VERTO_EV_PRIORITY_DEFAULT, cb, NULL, fds[0], VERTO_EV_IO_FLAG_READ));
+ assert(verto_add_timeout(ctx, VERTO_EV_PRIORITY_DEFAULT, VERTO_EV_FLAG_NONE, timeout_cb, NULL, 1000));
+ assert(verto_add_io(ctx, VERTO_EV_PRIORITY_DEFAULT, VERTO_EV_FLAG_PERSIST, cb, NULL, fds[0], VERTO_EV_IO_FLAG_READ));
assert(write(fds[1], DATA, DATALEN) == DATALEN);
return 0;
}
diff --git a/tests/signal.c b/tests/signal.c
index c58077a..32bf8d5 100644
--- a/tests/signal.c
+++ b/tests/signal.c
@@ -64,11 +64,11 @@ do_test(struct vertoEvCtx *ctx)
pid_t pid = 0;
count = 0;
- if (!verto_add_signal(ctx, VERTO_EV_PRIORITY_DEFAULT, cb, NULL, SIGUSR1)) {
+ if (!verto_add_signal(ctx, VERTO_EV_PRIORITY_DEFAULT, VERTO_EV_FLAG_PERSIST, cb, NULL, SIGUSR1)) {
printf("WARNING: Signal not supported!\n");
count = 2;
} else {
- verto_add_signal(ctx, VERTO_EV_PRIORITY_DEFAULT,
+ verto_add_signal(ctx, VERTO_EV_PRIORITY_DEFAULT, VERTO_EV_FLAG_NONE,
VERTO_SIG_IGN, NULL, SIGUSR2);
pid = fork();
@@ -85,8 +85,8 @@ do_test(struct vertoEvCtx *ctx)
}
}
- verto_add_timeout(ctx, VERTO_EV_PRIORITY_DEFAULT, exit_cb,
- (void *) (uintptr_t) pid, 100);
+ verto_add_timeout(ctx, VERTO_EV_PRIORITY_DEFAULT, VERTO_EV_FLAG_NONE,
+ exit_cb, (void *) (uintptr_t) pid, 100);
return 0;
}
diff --git a/tests/test.h b/tests/test.h
index 312d2cd..612b581 100644
--- a/tests/test.h
+++ b/tests/test.h
@@ -22,10 +22,12 @@
* SOFTWARE.
*/
+#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <signal.h>
+#include <string.h>
#include <verto.h>
@@ -82,3 +84,14 @@ main(int argc, char **argv)
return retval;
}
+
+void *passert(void *p) {
+ assert(p);
+ return p;
+}
+
+#define new0(type) _new0(sizeof(type))
+void * _new0(ssize_t size) {
+ void *p = malloc(size);
+ return passert(p ? memset(p, 0, size) : p);
+}
diff --git a/tests/timeout.c b/tests/timeout.c
index af10524..086ee5e 100644
--- a/tests/timeout.c
+++ b/tests/timeout.c
@@ -26,46 +26,55 @@
#include "test.h"
+#define SLEEP 10
#define M2U(m) ((m) * 1000)
-static struct timeval starttime;
-static struct timeval endtime;
+static int callcount;
+struct timeval starttime;
-void
+static bool
+elapsed(time_t min, time_t max)
+{
+ struct timeval tv;
+ long long diff;
+
+ assert(gettimeofday(&tv, NULL) == 0);
+ diff = (tv.tv_sec - starttime.tv_sec) * M2U(1000)
+ + tv.tv_usec - starttime.tv_usec;
+
+ assert(gettimeofday(&starttime, NULL) == 0);
+ if (diff < M2U(min) || diff > M2U(max)) {
+ printf("ERROR: Timeout is out-of-bounds!\n");
+ return false;
+ }
+ return true;
+}
+
+static void
exit_cb(struct vertoEvCtx *ctx, struct vertoEv *ev)
{
+ assert(callcount == 3);
verto_break(ctx);
}
-void
+static void
cb(struct vertoEvCtx *ctx, struct vertoEv *ev)
{
- long long diff;
-
- if (starttime.tv_sec == endtime.tv_sec && starttime.tv_usec == endtime.tv_usec) {
- gettimeofday(&endtime, NULL);
-
- diff = (endtime.tv_sec - starttime.tv_sec) * M2U(1000)
- + endtime.tv_usec - starttime.tv_usec;
-
- retval = diff < M2U(50) || diff > M2U(100);
- if (retval != 0)
- printf("ERROR: Timeout is out-of-bounds!\n");
- verto_add_timeout(ctx, VERTO_EV_PRIORITY_DEFAULT, exit_cb, NULL, 100);
- return;
+ assert(elapsed(SLEEP, SLEEP*2));
+ if (++callcount == 3)
+ assert(verto_add_timeout(ctx, VERTO_EV_PRIORITY_DEFAULT, VERTO_EV_FLAG_NONE, exit_cb, NULL, SLEEP*2));
+ else if (callcount == 2) {
+ assert(verto_add_timeout(ctx, VERTO_EV_PRIORITY_DEFAULT, VERTO_EV_FLAG_NONE, cb, NULL, SLEEP));
+ verto_del(ev);
}
-
- printf("ERROR: Timeout must not repeat!\n");
- retval = 1;
- exit_cb(ctx, ev);
}
int
do_test(struct vertoEvCtx *ctx)
{
- gettimeofday(&starttime, NULL);
- endtime = starttime;
+ callcount = 0;
- assert(verto_add_timeout(ctx, VERTO_EV_PRIORITY_DEFAULT, cb, NULL, 50));
+ assert(gettimeofday(&starttime, NULL) == 0);
+ assert(verto_add_timeout(ctx, VERTO_EV_PRIORITY_DEFAULT, VERTO_EV_FLAG_PERSIST, cb, NULL, SLEEP));
return 0;
}
diff --git a/tests/write.c b/tests/write.c
index daf17a6..350564b 100644
--- a/tests/write.c
+++ b/tests/write.c
@@ -76,7 +76,7 @@ read_cb(struct vertoEvCtx *ctx, struct vertoEv *ev)
fds[0] = -1;
verto_del(ev); /* We don't want this callback called because of close() */
- assert(verto_add_io(ctx, VERTO_EV_PRIORITY_DEFAULT, error_cb, NULL, fds[1], VERTO_EV_IO_FLAG_WRITE));
+ assert(verto_add_io(ctx, VERTO_EV_PRIORITY_DEFAULT, VERTO_EV_FLAG_PERSIST, error_cb, NULL, fds[1], VERTO_EV_IO_FLAG_WRITE));
}
static void
@@ -88,7 +88,7 @@ write_cb(struct vertoEvCtx *ctx, struct vertoEv *ev)
assert(write(fd, DATA, DATALEN) == DATALEN);
verto_del(ev);
- assert(verto_add_io(ctx, VERTO_EV_PRIORITY_DEFAULT, read_cb, NULL, fds[0], VERTO_EV_IO_FLAG_READ));
+ assert(verto_add_io(ctx, VERTO_EV_PRIORITY_DEFAULT, VERTO_EV_FLAG_PERSIST, read_cb, NULL, fds[0], VERTO_EV_IO_FLAG_READ));
}
int
@@ -98,11 +98,11 @@ do_test(struct vertoEvCtx *ctx)
fds[0] = -1;
fds[1] = -1;
- if (!verto_add_signal(ctx, VERTO_EV_PRIORITY_DEFAULT, VERTO_SIG_IGN, NULL, SIGPIPE))
+ if (!verto_add_signal(ctx, VERTO_EV_PRIORITY_DEFAULT, VERTO_EV_FLAG_NONE, VERTO_SIG_IGN, NULL, SIGPIPE))
signal(SIGPIPE, SIG_IGN);
assert(pipe(fds) == 0);
- assert(verto_add_timeout(ctx, VERTO_EV_PRIORITY_DEFAULT, timeout_cb, NULL, 1000));
- assert(verto_add_io(ctx, VERTO_EV_PRIORITY_DEFAULT, write_cb, NULL, fds[1], VERTO_EV_IO_FLAG_WRITE));
+ assert(verto_add_timeout(ctx, VERTO_EV_PRIORITY_DEFAULT, VERTO_EV_FLAG_NONE, timeout_cb, NULL, 1000));
+ assert(verto_add_io(ctx, VERTO_EV_PRIORITY_DEFAULT, VERTO_EV_FLAG_PERSIST, write_cb, NULL, fds[1], VERTO_EV_IO_FLAG_WRITE));
return 0;
}