mirror of
https://github.com/troglobit/libuev.git
synced 2026-10-15 10:19:31 +00:00
Major refactor: API change, code cleanup, remove calloc()/free()
- Rename all _create() functions --> _init() - Rename all _delete() functions --> _stop() - Watchers are automatically started, except - Timer watchers are automatically started by uev_run() - Allow I/O watchers to watch either EV_READ/EV_WRITE or both events - Extend callbacks with a received events field - Remove calloc()/free(), let user handle this - Make event has-a context when initializing it => simplifies API - Internal uev_watcher_*() API mostly handles epoll stop/start Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
1 parent
c69ce87eb8
commit
d6e0146803
7 files changed
+362
-279
No files matched your search
@@ -30,105 +30,113 @@
|
||||
|
||||
#include "uev.h"
|
||||
|
||||
#define UNUSED(arg) arg __attribute__ ((unused))
|
||||
|
||||
typedef struct {
|
||||
int counter;
|
||||
} my_t;
|
||||
|
||||
static int in, out;
|
||||
static int period = 0;
|
||||
static uev_t *timer = NULL;
|
||||
static uev_t *watchdog;
|
||||
|
||||
static void lifetime_cb(uev_ctx_t *ctx, uev_t *w __attribute__ ((unused)), void *data)
|
||||
static void lifetime_cb(uev_ctx_t *ctx, uev_t UNUSED(*w), void *arg, int UNUSED(events))
|
||||
{
|
||||
fprintf(stderr, "\nLifetime exceeded %p\n", data);
|
||||
fprintf(stderr, "\nLifetime exceeded %p\n", arg);
|
||||
uev_exit(ctx);
|
||||
}
|
||||
|
||||
/* The pipe watchdog, if it triggers we haven't received data in time. */
|
||||
static void timeout_cb(uev_ctx_t *ctx, uev_t *w, void *data)
|
||||
static void timeout_cb(uev_ctx_t *ctx, uev_t *w, void *arg, int UNUSED(events))
|
||||
{
|
||||
timer = NULL;
|
||||
fprintf(stderr, "\nTimeout exceeded %p\n", data);
|
||||
watchdog = NULL;
|
||||
fprintf(stderr, "\nTimeout exceeded %p\n", arg);
|
||||
|
||||
uev_timer_delete(ctx, w);
|
||||
uev_timer_stop(w);
|
||||
uev_exit(ctx);
|
||||
}
|
||||
|
||||
static void periodic_task(uev_ctx_t *ctx __attribute__ ((unused)), uev_t *w __attribute__ ((unused)), void *data __attribute__ ((unused)))
|
||||
static void periodic_task(uev_ctx_t UNUSED(*ctx), uev_t UNUSED(*w), void UNUSED(*arg), int UNUSED(events))
|
||||
{
|
||||
fprintf(stderr, "|");
|
||||
}
|
||||
|
||||
static void signal_cb(uev_ctx_t *ctx __attribute__ ((unused)), uev_t *w, void *data __attribute__ ((unused)))
|
||||
static void signal_cb(uev_ctx_t *UNUSED(ctx), uev_t *w, void *UNUSED(arg), int UNUSED(events))
|
||||
{
|
||||
fprintf(stderr, w->signo == SIGINT ? "^Cv" : "^\v");
|
||||
}
|
||||
|
||||
static void pipe_read_cb(uev_ctx_t *ctx, uev_t *w __attribute__ ((unused)), void *data __attribute__ ((unused)))
|
||||
static void pipe_read_cb(uev_ctx_t *UNUSED(ctx), uev_t UNUSED(*w), void UNUSED(*arg), int UNUSED(events))
|
||||
{
|
||||
int cnt;
|
||||
char msg[50];
|
||||
|
||||
/* Kick watchdog */
|
||||
if (timer)
|
||||
uev_timer_set(ctx, timer, 1000, 0);
|
||||
if (watchdog)
|
||||
uev_timer_set(watchdog, 1000, 0);
|
||||
|
||||
cnt = read(in, msg, sizeof(msg));
|
||||
// fprintf(stderr, "READ %.*s %d\n", cnt, msg, cnt);
|
||||
fprintf(stderr, "%.*s.%d ", cnt, msg, cnt);
|
||||
}
|
||||
|
||||
static void pipe_write_cb(uev_ctx_t *ctx, uev_t *w __attribute__ ((unused)), void *data)
|
||||
static void pipe_write_cb(uev_ctx_t UNUSED(*ctx), uev_t *w, void *arg, int UNUSED(events))
|
||||
{
|
||||
int cnt = (int)(intptr_t)data;
|
||||
my_t *my = arg;
|
||||
char *msg = "TESTING";
|
||||
|
||||
if (write(out, msg, cnt) < 0) {
|
||||
if (write(out, msg, my->counter) < 0) {
|
||||
perror("\nFailed writing to pipe");
|
||||
return;
|
||||
}
|
||||
|
||||
// fprintf(stderr, "WRITE %.*s %d\n", cnt, msg, cnt);
|
||||
fprintf(stderr, "%d ", cnt);
|
||||
period = cnt + 5;
|
||||
// fprintf(stderr, "WRITE %.*s %d\n", my->counter, msg, my->counter);
|
||||
fprintf(stderr, "%d ", my->counter);
|
||||
period = my->counter + 5;
|
||||
my->counter++;
|
||||
|
||||
uev_timer_create(ctx, pipe_write_cb, (void *)(intptr_t)(cnt + 1), period * 100, 0);
|
||||
uev_timer_set(w, period * 100, 0);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fd[2];
|
||||
uev_ctx_t *ctx = uev_ctx_create();
|
||||
|
||||
/* Total program execution time */
|
||||
uev_timer_create(ctx, lifetime_cb, (void *)(intptr_t)2, 4000, 0);
|
||||
my_t my = { .counter = 1 };
|
||||
uev_t timeout, wdt, periodic, writer, reader, sigint_watcher, sigquit_watcher;
|
||||
uev_ctx_t ctx;
|
||||
|
||||
/* 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);
|
||||
if (pipe(fd) < 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
uev_init(&ctx);
|
||||
|
||||
/* Signal watchers, Ctrl-C => SIGINT, Ctrl-\ => SIGQUIT */
|
||||
uev_signal_init(&ctx, &sigint_watcher, signal_cb, NULL, SIGINT);
|
||||
uev_signal_init(&ctx, &sigquit_watcher, signal_cb, NULL, SIGQUIT);
|
||||
|
||||
/* Total program execution time */
|
||||
uev_timer_init(&ctx, &timeout, lifetime_cb, (void *)(intptr_t)2, 4000, 0);
|
||||
|
||||
/* Main pipe worker and consumer */
|
||||
in = fd[0];
|
||||
out = fd[1];
|
||||
uev_timer_create(ctx, pipe_write_cb, (void *)(intptr_t)1, 400, 0);
|
||||
uev_io_create(ctx, pipe_read_cb, NULL, in, UEV_DIR_INBOUND);
|
||||
uev_io_init(&ctx, &reader, pipe_read_cb, NULL, in, UEV_READ);
|
||||
uev_timer_init(&ctx, &writer, pipe_write_cb, &my, 400, 0);
|
||||
|
||||
/* 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, timeout_cb, (void *)(intptr_t)1, 950, 0);
|
||||
uev_timer_init(&ctx, &wdt, timeout_cb, (void *)(intptr_t)1, 950, 0);
|
||||
watchdog = &wdt;
|
||||
|
||||
/* Periodic background task */
|
||||
uev_timer_create(ctx, periodic_task, NULL, 200, 200);
|
||||
|
||||
/* Signal watchers, Ctrl-C => SIGINT, Ctrl-\ => SIGQUIT */
|
||||
uev_signal_create(ctx, signal_cb, NULL, SIGINT);
|
||||
uev_signal_create(ctx, signal_cb, NULL, SIGQUIT);
|
||||
uev_timer_init(&ctx, &periodic, periodic_task, NULL, 200, 200);
|
||||
|
||||
/* Start event loop */
|
||||
uev_run(ctx);
|
||||
|
||||
/* Tear down event context */
|
||||
uev_ctx_delete(ctx);
|
||||
uev_run(&ctx);
|
||||
|
||||
fprintf(stderr, "Period is %d must be 10: %s\n", period, 10 == period ? "OK" : "ERROR!");
|
||||
if (10 != period)
|
||||
|
||||
Reference in new issue
Block a user