]> granicus.if.org Git - libevent/commitdiff
Patch from Valery Kholodkov: support for edge-triggered events with epoll and kqueue...
authorNick Mathewson <nickm@torproject.org>
Fri, 30 May 2008 16:56:34 +0000 (16:56 +0000)
committerNick Mathewson <nickm@torproject.org>
Fri, 30 May 2008 16:56:34 +0000 (16:56 +0000)
svn:r840

ChangeLog
epoll.c
include/event2/event.h
kqueue.c
test/Makefile.am
test/regress.c
test/regress.h

index 16ec4595562a5a356226191e50b9429724d3aca9..c934f35caa1a8b7f37b50bfb943b6f2eb15a13d0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -103,8 +103,9 @@ Changes in current version:
  o Fix use of freed memory in event_reinit; pointed out by Peter Postma
  o constify struct timeval * where possible
  o make event_get_supported_methods obey environment variables
+ o support for edge-triggered events on epoll and kqueue backends: patch from Valery Kholodkov
+
 
-        
 Changes in 1.4.0:
  o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr.
  o demote most http warnings to debug messages
diff --git a/epoll.c b/epoll.c
index 423d989820253c629334b34a1e7b100fd24b9e1d..0b718cc85563032e6b58ec30619217b9b7c2ddb0 100644 (file)
--- a/epoll.c
+++ b/epoll.c
@@ -241,9 +241,9 @@ epoll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
                        continue;
 
                if (evread != NULL)
-                       event_active(evread, EV_READ, 1);
+                       event_active(evread, EV_READ | (evread->ev_events & EV_ET), 1);
                if (evwrite != NULL)
-                       event_active(evwrite, EV_WRITE, 1);
+                       event_active(evwrite, EV_WRITE | (evwrite->ev_events & EV_ET), 1);
        }
 
        return (0);
@@ -283,6 +283,8 @@ epoll_add(void *arg, struct event *ev)
                events |= EPOLLIN;
        if (ev->ev_events & EV_WRITE)
                events |= EPOLLOUT;
+       if(ev->ev_events & EV_ET)
+               events |= EPOLLET;
 
        epev.data.ptr = evep;
        epev.events = events;
index 5702b9391db979f9881e89b977f9f3f4acaf7da1..4cd4608ddeae32efd0d360dfe5a4948defec54be 100644 (file)
@@ -258,12 +258,16 @@ void evperiodic_assign(struct event *ev, struct event_base *base,
     const struct timeval *tv, void (*cb)(int, short, void *), void *arg);
 
 /* Flags to pass to event_set(), event_new(), event_assign(),
- * event_pending()... */
+ * event_pending(), and anything else with an argument of the form
+ * "short events" */
 #define EV_TIMEOUT     0x01
 #define EV_READ                0x02
 #define EV_WRITE       0x04
 #define EV_SIGNAL      0x08
-#define EV_PERSIST     0x10    /* Persistant event */
+/** Persistent event: won't get removed automatically when activated. */
+#define EV_PERSIST     0x10
+/** Select edge-triggered behavior, if supported by the backend. */
+#define EV_ET       0x20
 
 /**
   Define a timer event.
@@ -321,6 +325,11 @@ void evperiodic_assign(struct event *ev, struct event_base *base,
   EV_READ, or EV_WRITE.  The additional flag EV_PERSIST makes an event_add()
   persistent until event_del() has been called.
 
+  For read and write events, edge-triggered behavior can be requested
+  with the EV_ET flag.  Not all backends support edge-triggered
+  behavior.  When an edge-triggered event is activated, the EV_ET flag
+  is added to its events argument.
+
   @param ev an event struct to be modified
   @param fd the file descriptor to be monitored
   @param event desired events to monitor; can be EV_READ and/or EV_WRITE
index b213be02e1fac4003da5d7399d3d02a1bc616d00..38278938c376328b0ec554dc50133f1510b4f126 100644 (file)
--- a/kqueue.c
+++ b/kqueue.c
@@ -272,7 +272,7 @@ kq_dispatch(struct event_base *base, void *arg, struct timeval *tv)
                if (!(ev->ev_events & EV_PERSIST))
                        ev->ev_flags &= ~EVLIST_X_KQINKERNEL;
 
-               event_active(ev, which,
+               event_active(ev, which | (ev->ev_events & EV_ET),
                    ev->ev_events & EV_SIGNAL ? events[i].data : 1);
        }
 
@@ -322,6 +322,8 @@ kq_add(void *arg, struct event *ev)
                kev.flags = EV_ADD;
                if (!(ev->ev_events & EV_PERSIST))
                        kev.flags |= EV_ONESHOT;
+               if (ev->ev_events & EV_ET)
+                       kev.flags |= EV_CLEAR;
                kev.udata = PTR_TO_UDATA(ev);
                
                if (kq_insert(kqop, &kev) == -1)
@@ -337,6 +339,8 @@ kq_add(void *arg, struct event *ev)
                kev.flags = EV_ADD;
                if (!(ev->ev_events & EV_PERSIST))
                        kev.flags |= EV_ONESHOT;
+               if (ev->ev_events & EV_ET)
+                       kev.flags |= EV_CLEAR;
                kev.udata = PTR_TO_UDATA(ev);
                
                if (kq_insert(kqop, &kev) == -1)
index 2e3b77678f1b55a0abfda3749b8525d67363c826..4f89eeceb07848045cd865adcc26aaaa42f9ec12 100644 (file)
@@ -17,7 +17,7 @@ test_weof_LDADD = ../libevent_core.la
 test_time_SOURCES = test-time.c
 test_time_LDADD = ../libevent_core.la
 regress_SOURCES = regress.c regress.h regress_http.c regress_dns.c \
-       regress_rpc.c regress.gen.c regress.gen.h
+       regress_rpc.c regress.gen.c regress.gen.h regress_et.c
 if PTHREAD_REGRESS
 regress_SOURCES += regress_pthread.c
 endif
index ca83e879b6d36ee92c5fc7d07916c0dffb1eff9d..a6ca9b4d4a1105775ddbfbe2768b2602ec7a1323 100644 (file)
@@ -2185,7 +2185,7 @@ main (int argc, char **argv)
        test_evbuffer_iterative();
        test_evbuffer_readln();
        test_evbuffer_find();
-       
+
        test_bufferevent();
        test_bufferevent_watermarks();
        test_bufferevent_filters();
@@ -2201,7 +2201,7 @@ main (int argc, char **argv)
 #if defined(HAVE_LIBZ)
        regress_zlib();
 #endif
-       
+
        http_suite();
 
        rpc_suite();
@@ -2224,6 +2224,8 @@ main (int argc, char **argv)
 
        test_simpletimeout();
 
+    test_edgetriggered();
+
 #ifndef WIN32
        test_simplesignal();
        test_immediatesignal();
index 5ac6dff9a2281cbbea7cc7934250b978a4ee1991..cb92c9ea3249eb1270ce9c078158e1d0ae82780e 100644 (file)
@@ -39,7 +39,9 @@ void rpc_suite(void);
 void dns_suite(void);
 
 void regress_pthread(void);
-void regress_zlib(void);       
+void regress_zlib(void);
+
+void test_edgetriggered(void);
 
 #ifdef __cplusplus
 }