]> granicus.if.org Git - libevent/commitdiff
support for periodic timeouts
authorNiels Provos <provos@gmail.com>
Sat, 3 May 2008 22:10:09 +0000 (22:10 +0000)
committerNiels Provos <provos@gmail.com>
Sat, 3 May 2008 22:10:09 +0000 (22:10 +0000)
svn:r762

ChangeLog
event.c
include/event2/event.h
include/event2/event_struct.h
test/regress.c

index b3bc09ccf0cd466fc904278ce9482e7957112328..d5d7231f3dc0fb7bb337bbb1be8fa356fae89e68 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -87,6 +87,7 @@ Changes in current version:
  o introduce evbuffer_reserve_space() and evbuffer_commit_space() to make processing in filters more efficient.
  o reduce system calls for getting current time by caching it.
  o separate signal events from io events; making the code less complex.
+ o support for periodic timeouts
        
 Changes in 1.4.0:
  o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr.
diff --git a/event.c b/event.c
index 740d8f08de78a851c805c75bccad5be5a5625bea..729ac8f70cc5c7ab1e60094240385338dbf138ab 100644 (file)
--- a/event.c
+++ b/event.c
@@ -137,6 +137,7 @@ static void timeout_process(struct event_base *);
 static void    timeout_correct(struct event_base *, struct timeval *);
 
 static void    event_signal_closure(struct event_base *, struct event *ev);
+static void    event_periodic_closure(struct event_base *, struct event *ev);
 
 static void
 detect_monotonic(void)
@@ -362,6 +363,13 @@ event_haveevents(struct event_base *base)
        return (base->event_count > 0);
 }
 
+static void
+event_periodic_closure(struct event_base *base, struct event *ev)
+{
+       event_add(ev, &ev->_ev.ev_periodic.tv_interval);
+       (*ev->ev_callback)((int)ev->ev_fd, ev->ev_res, ev->ev_arg);
+}
+
 static void
 event_signal_closure(struct event_base *base, struct event *ev)
 {
@@ -709,6 +717,16 @@ event_assign(struct event *ev, struct event_base *base, evutil_socket_t fd, shor
                return (0);
 }
 
+void
+evperiodic_assign(struct event *ev, struct event_base *base,
+    struct timeval *tv, void (*cb)(evutil_socket_t, short, void *), void *arg)
+{
+       event_assign(ev, base, -1, EV_TIMEOUT, cb, arg);
+       
+       ev->_ev.ev_periodic.tv_interval = *tv;
+       ev->ev_closure = event_periodic_closure;
+}
+
 struct event *
 event_new(struct event_base *base, evutil_socket_t fd, short events, void (*cb)(evutil_socket_t, short, void *), void *arg)
 {
index b85bc496ee49d3c52f481ed912f255ab2c0b97b3..840092cbb17794f6147919e6fffbe7051e154ea6 100644 (file)
@@ -184,6 +184,22 @@ int event_base_loopexit(struct event_base *, struct timeval *);
  */
 int event_base_loopbreak(struct event_base *);
 
+/**
+   Define a periodic timer.
+
+   Behaves like a timer only that it repeats at the specified interval.
+   To start this time, it needs to be added via event_add().
+
+   @param ev event struct to be modified
+   @param base the event base to which this event belongs
+   @param tv periodicity interval
+   @param cb callback function
+   @param arg argument that will be passed to the callback function
+*/
+
+void evperiodic_assign(struct event *ev, struct event_base *base,
+    struct timeval *tv, void (*cb)(int, short, void *), void *arg);
+
 /**
   Define a timer event.
 
index b85e4528fbdc36ec3dffc24af711f0db16f8d9ac..56e240772c097c071a2ed48f4d81b4a32f5c4805 100644 (file)
@@ -104,6 +104,10 @@ struct event {
                        /* Allows deletes in callback */
                        short *ev_pncalls;
                } ev_signal;
+
+               struct {
+                       struct timeval tv_interval;
+               } ev_periodic;
        } _ev;
 
        short ev_events;
index 993fba540f8c69ebfbd2add7c31dc81ae0eadafd..a7321835b539ff89a0a095fe5db1226efb674911 100644 (file)
@@ -432,6 +432,43 @@ test_simpletimeout(void)
        cleanup_test();
 }
 
+static void
+periodic_timeout_cb(int fd, short event, void *arg)
+{
+       int *count = arg;
+
+       (*count)++;
+       if (*count > 5) {
+               test_ok = 1;
+               event_base_loopexit(global_base, NULL);
+       }
+}
+
+static void
+test_periodictimeout(void)
+{
+       struct timeval tv, tv_interval;
+       struct event ev;
+       int count = 0;
+
+       setup_test("Periodic timeout: ");
+
+       timerclear(&tv_interval);
+       tv_interval.tv_usec = 10000;
+
+       tv.tv_usec = 0;
+       tv.tv_sec = 0;
+       evperiodic_assign(&ev, global_base, &tv_interval,
+           periodic_timeout_cb, &count);
+       event_add(&ev, &tv);
+
+       event_dispatch();
+
+       event_del(&ev);
+
+       cleanup_test();
+}
+
 #ifndef WIN32
 extern struct event_base *current_base;
 static void
@@ -2044,6 +2081,8 @@ main (int argc, char **argv)
 
         test_evutil_strtoll();
 
+       test_periodictimeout();
+
        /* use the global event base and need to be called first */
        test_priorities(1);
        test_priorities(2);
@@ -2091,6 +2130,7 @@ main (int argc, char **argv)
        test_combined();
 
        test_simpletimeout();
+
 #ifndef WIN32
        test_simplesignal();
        test_immediatesignal();