From: Niels Provos Date: Mon, 22 Mar 2004 21:46:45 +0000 (+0000) Subject: support event_loopexit(); idea from marius; and fix event_once() X-Git-Tag: release-1.1b~75 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cd699abf44d6da49dffff09f72f843bbb0211aae;p=libevent support event_loopexit(); idea from marius; and fix event_once() svn:r94 --- diff --git a/event.3 b/event.3 index 0a355cef..fee5f3f5 100644 --- a/event.3 +++ b/event.3 @@ -33,6 +33,7 @@ .Nm event_init , .Nm event_dispatch , .Nm event_loop , +.Nm event_loopexit , .Nm event_set , .Nm event_add , .Nm event_del , @@ -59,6 +60,8 @@ .Fn "event_dispatch" .Ft int .Fn "event_loop" "int flags" +.Ft int +.Fn "event_loopexit" "struct timeval *tv" .Ft void .Fn "event_set" "struct event *ev" "int fd" "short event" "void (*fn)(int, short, void *)" "void *arg" .Ft int @@ -146,6 +149,11 @@ events. The flags and .Va EVLOOP_NONBLOCK are recognized. +The +.Nm event_loopexit +function allows the loop to be terminated after some amount of time +has passed. +The parameter indicates the time after which the loop should terminate. .Pp It is the responsibility of the caller to provide these functions with pre-allocated event structures. diff --git a/event.c b/event.c index ec08e142..3cf61b45 100644 --- a/event.c +++ b/event.c @@ -1,7 +1,5 @@ -/* $OpenBSD: event.c,v 1.2 2002/06/25 15:50:15 mickey Exp $ */ - /* - * Copyright 2000-2002 Niels Provos + * Copyright (c) 2000-2004 Niels Provos * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -108,16 +106,18 @@ const struct eventop *eventops[] = { const struct eventop *evsel; void *evbase; -/* Handle signals */ +/* Handle signals - This is a deprecated interface */ int (*event_sigcb)(void); /* Signal callback when gotsig is set */ int event_gotsig; /* Set in signal handler */ +int event_gotterm; /* Set to terminate loop */ /* Prototypes */ -void event_queue_insert(struct event *, int); -void event_queue_remove(struct event *, int); -int event_haveevents(void); -void event_process_active(void); -void timeout_insert(struct event *); +void event_queue_insert(struct event *, int); +void event_queue_remove(struct event *, int); +int event_haveevents(void); +void timeout_insert(struct event *); + +static void event_process_active(void); static RB_HEAD(event_tree, event) timetree; static struct event_list activequeue; @@ -180,7 +180,7 @@ event_haveevents(void) TAILQ_FIRST(&signalqueue) || TAILQ_FIRST(&activequeue)); } -void +static void event_process_active(void) { struct event *ev; @@ -201,12 +201,28 @@ event_process_active(void) } } +/* + * Wait continously for events. We exit only if no events are left. + */ + int event_dispatch(void) { return (event_loop(0)); } +static void +event_loopexit_cb(int fd, short what, void *arg) +{ + event_gotterm = 1; +} + +int +event_loopexit(struct timeval *tv) +{ + return (event_once(-1, EV_TIMEOUT, event_loopexit_cb, NULL, tv)); +} + int event_loop(int flags) { @@ -219,6 +235,12 @@ event_loop(int flags) done = 0; while (!done) { + /* Terminate the loop if we have been asked to */ + if (event_gotterm) { + event_gotterm = 0; + done = 1; + } + while (event_gotsig) { event_gotsig = 0; if (event_sigcb) { @@ -314,11 +336,11 @@ event_once(int fd, short events, eonce->cb = callback; eonce->arg = arg; - evtimer_set(&eonce->ev, event_once_cb, &eonce); + evtimer_set(&eonce->ev, event_once_cb, eonce); } else if (events & (EV_READ|EV_WRITE)) { events &= EV_READ|EV_WRITE; - event_set(&eonce->ev, fd, events, event_once_cb, &eonce); + event_set(&eonce->ev, fd, events, event_once_cb, eonce); } else { /* Bad event combination */ return (-1); diff --git a/event.h b/event.h index ed09afc6..c393c388 100644 --- a/event.h +++ b/event.h @@ -1,5 +1,5 @@ /* - * Copyright 2000-2002 Niels Provos + * Copyright (c) 2000-2004 Niels Provos * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -126,6 +126,7 @@ int event_dispatch(void); #define EVLOOP_ONCE 0x01 #define EVLOOP_NONBLOCK 0x02 int event_loop(int); +int event_loopexit(struct timeval *); /* Causes the loop to exit */ int timeout_next(struct timeval *); void timeout_correct(struct timeval *); @@ -174,12 +175,54 @@ struct evbuffer { size_t off; }; +#define EVBUFFER_READ 0x01 +#define EVBUFFER_WRITE 0x02 +#define EVBUFFER_EOF 0x10 +#define EVBUFFER_ERROR 0x20 +#define EVBUFFER_TIMEOUT 0x40 + +struct bufferevent; +typedef void (*evbuffercb)(struct bufferevent *, void *); +typedef void (*everrorcb)(struct bufferevent *, short what, void *); + +struct bufferevent { + struct event ev_read; + struct event ev_write; + + struct evbuffer *input; + struct evbuffer *output; + + evbuffercb readcb; + evbuffercb writecb; + everrorcb errorcb; + void *cbarg; + + int timeout_read; /* in seconds */ + int timeout_write; /* in seconds */ + + short enabled; /* events that are currently enabled */ +}; + +struct bufferevent *bufferevent_new(int fd, + evbuffercb readcb, evbuffercb writecb, everrorcb errorcb, void *cbarg); +int bufferevent_write(struct bufferevent *bufev, void *data, size_t size); +int bufferevent_write_buffer(struct bufferevent *bufev, struct evbuffer *buf); +size_t bufferevent_read(struct bufferevent *bufev, void *data, size_t size); +int bufferevent_enable(struct bufferevent *bufev, short event); +int bufferevent_disable(struct bufferevent *bufev, short event); +void bufferevent_settimeout(struct bufferevent *bufev, + int timeout_read, int timeout_write); + #define EVBUFFER_LENGTH(x) (x)->off +#define EVBUFFER_DATA(x) (x)->buffer +#define EVBUFFER_INPUT(x) (x)->input +#define EVBUFFER_OUTPUT(x) (x)->output struct evbuffer *evbuffer_new(void); void evbuffer_free(struct evbuffer *); -void evbuffer_add(struct evbuffer *, u_char *, size_t); -void evbuffer_add_buffer(struct evbuffer *, struct evbuffer *); +void evbuffer_free(struct evbuffer *); +int evbuffer_add(struct evbuffer *, u_char *, size_t); +int evbuffer_add_buffer(struct evbuffer *, struct evbuffer *); int evbuffer_add_printf(struct evbuffer *, char *fmt, ...); void evbuffer_drain(struct evbuffer *, size_t); int evbuffer_write(struct evbuffer *, int);