Add support for peridic timers and resetting timers

Refactor uev_timer_create() to support a periodic (msec) argument. For
such timers libuev automaticlly respawns them.  Effectively resetting
the timeout using the period value.

Also, refactor argument order to uev_timer_create() and uev_io_create().

Rename UEV_FHIN, UEV_FHOUT to UEV_DIR_INBOUND and UEV_DIR_OUTBOUND.

Remove unnecessary return value for watcher callbacks.  What would those
have been usefu for, ever?  Not even the original code checked the return
value after calling a handler.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson committed 2013-07-21 11:39:26 +02:00
1 parent 97398e0a7d
commit ec9351bfdd
3 files changed
+140 -78

No files matched your search

+40 -33
View File
@@ -33,57 +33,56 @@ static int in, out;
static int period = 0;
static uev_timer_t *timer = NULL;
static int lifetime_cb(uev_t *ctx, uev_timer_t *w, void *data)
static void lifetime_cb(uev_t *ctx, uev_timer_t *w __attribute__ ((unused)), void *data)
{
fprintf(stderr, "\nLifetime exceeded %p\n", data);
uev_exit(ctx);
return 0;
}
/* The pipe watchdog, if it triggers we haven't received data in time. */
static int timeout_cb(uev_t *ctx, uev_timer_t *w, void *data)
static void timeout_cb(uev_t *ctx, uev_timer_t *w, void *data)
{
timer = NULL;
fprintf(stderr, "\nTimeout exceeded %p\n", data);
uev_timer_delete(ctx, w);
uev_exit(ctx);
return 0;
}
static int pipe_read_cb(uev_t *ctx, uev_io_t *w, int fd, void *data)
static void periodic_task(uev_t *ctx __attribute__ ((unused)), uev_timer_t *w __attribute__ ((unused)), void *data __attribute__ ((unused)))
{
fprintf(stderr, "|");
}
static void pipe_read_cb(uev_t *ctx, uev_io_t *w __attribute__ ((unused)), void *data __attribute__ ((unused)))
{
int cnt;
char msg[50];
/* Kick watchdog */
if (timer) {
uev_timer_delete(ctx, timer);
timer = uev_timer_create(ctx, 1000, timeout_cb, NULL);
}
if (timer)
uev_timer_set(ctx, timer, 1000, 0);
cnt = read(in, msg, sizeof(msg));
// fprintf(stderr, "READ %.*s %d\n", cnt, msg, cnt);
fprintf(stderr, "%.*s.%d ", cnt, msg, cnt);
return 0;
}
static int pipe_write_cb(uev_t *ctx, uev_timer_t *handle, void *data)
static void pipe_write_cb(uev_t *ctx, uev_timer_t *w __attribute__ ((unused)), void *data)
{
int cnt = (int)(intptr_t)data;
char *msg = "TESTING";
write(out, msg, cnt);
if (write(out, msg, cnt) < 0) {
perror("\nFailed writing to pipe");
return;
}
// fprintf(stderr, "WRITE %.*s %d\n", cnt, msg, cnt);
fprintf(stderr, "%d ", cnt);
period = cnt + 5;
uev_timer_create(ctx, period * 100, pipe_write_cb, (void *)(intptr_t)(cnt + 1));
return 0;
uev_timer_create(ctx, pipe_write_cb, (void *)(intptr_t)(cnt + 1), period * 100, 0);
}
int main(void)
@@ -91,31 +90,39 @@ int main(void)
int fd[2];
uev_t *ctx = uev_ctx_create();
/* Total program execution time */
uev_timer_create(ctx, 4000, lifetime_cb, (void *)(intptr_t)2);
/* Total program execution time */
uev_timer_create(ctx, (uev_timer_cb_t)lifetime_cb, (void *)(intptr_t)2, 4000, 0);
/* Work load, one timer callback writes to a pipe periodically,
* and one I/O watcher that is called every time the pipe has
* some data. */
if (pipe(fd) < 0) {
/* Cleanup */
uev_ctx_delete(ctx);
return 1;
}
/* Work load, one timer callback writes to a pipe periodically,
* and one I/O watcher that is called every time the pipe has
* some data. */
pipe(fd);
in = fd[0];
out = fd[1];
uev_timer_create(ctx, 400, pipe_write_cb, (void *)(intptr_t)1);
uev_io_create(ctx, in, UEV_FHIN, pipe_read_cb, NULL);
uev_timer_create(ctx, (uev_timer_cb_t)pipe_write_cb, (void *)(intptr_t)1, 400, 0);
uev_io_create(ctx, (uev_io_cb_t)pipe_read_cb, NULL, in, UEV_DIR_INBOUND);
/* Watchdog for the above timer callback, if it doesn't wake up
* and write to the pipe within a given deadline it will bark. */
timer = uev_timer_create(ctx, 950, timeout_cb, (void *)(intptr_t)1);
/* Watchdog for the above timer callback, if it doesn't wake up
* and write to the pipe within a given deadline it will bark. */
timer = uev_timer_create(ctx, (uev_timer_cb_t)timeout_cb, (void *)(intptr_t)1, 950, 0);
/* Start event loop */
/* Periodic background task */
uev_timer_create(ctx, (uev_timer_cb_t)periodic_task, NULL, 200, 200);
/* Start event loop */
uev_run(ctx);
/* Tear down event context */
/* Tear down event context */
uev_ctx_delete(ctx);
fprintf(stderr, "Period is %d must be 10: %s\n", period, 10 == period ? "OK" : "ERROR!");
if (10 != period)
return 1;
if (10 != period)
return 1;
return 0;
}