]> granicus.if.org Git - libevent/commitdiff
support event_loopexit(); idea from marius; and fix event_once()
authorNiels Provos <provos@gmail.com>
Mon, 22 Mar 2004 21:46:45 +0000 (21:46 +0000)
committerNiels Provos <provos@gmail.com>
Mon, 22 Mar 2004 21:46:45 +0000 (21:46 +0000)
svn:r94

event.3
event.c
event.h

diff --git a/event.3 b/event.3
index 0a355cef5b19e5f91c7f84555bf79342acf8f941..fee5f3f5345015f206ef32dda5381d00839058d7 100644 (file)
--- 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 ec08e1427cd0ff9e4e7b2f514b374ae6a663d9eb..3cf61b452f0534dc20e39fcba2a79d934feec59a 100644 (file)
--- 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 <provos@citi.umich.edu>
+ * Copyright (c) 2000-2004 Niels Provos <provos@citi.umich.edu>
  * 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 ed09afc65c1d23dc2baaccfb70b8a202d7f72244..c393c3882c390d3202488323aaed1257a64f5cb8 100644 (file)
--- a/event.h
+++ b/event.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2002 Niels Provos <provos@citi.umich.edu>
+ * Copyright (c) 2000-2004 Niels Provos <provos@citi.umich.edu>
  * 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);