src/server/daemon/event_linux.c

branch
aio
changeset 192
6a145e13d933
parent 187
4384bfbb7e26
child 193
aa8393527b1e
--- a/src/server/daemon/event_linux.c	Sat Jan 13 16:44:05 2018 +0100
+++ b/src/server/daemon/event_linux.c	Sat Jan 13 18:48:19 2018 +0100
@@ -56,14 +56,18 @@
             // TODO: error
             return NULL;
         }
-        handler->eventfd = eventfd(0, 0);
-        if(handler->eventfd == 0) {
+        
+        int eventpipe[2];
+        if(pipe(eventpipe)) {
             return NULL;
         }
+        handler->eventin = eventpipe[0];
+        handler->eventout = eventpipe[1];
+        
         struct epoll_event epev;
         epev.events = EPOLLIN | EPOLLET; // input event, edge triggered
         epev.data.ptr = NULL;
-        if(epoll_ctl(handler->ep, EPOLL_CTL_ADD, handler->eventfd, &epev)) {
+        if(epoll_ctl(handler->ep, EPOLL_CTL_ADD, handler->eventin, &epev)) {
             return NULL;
         }
         
@@ -96,14 +100,25 @@
         for(int i=0;i<ret;i++) {
             Event *event = events[i].data.ptr;
             if(!event) {
-                ssize_t r = read(ev->eventfd, &event, sizeof(Event*));
-                if(r == sizeof(Event*)) {
+                char ebuf[sizeof(Event*)];
+                int ebufpos = 0;
+                char *b = ebuf;
+                while(ebufpos < sizeof(Event*)) {
+                    ssize_t r = read(ev->eventin, b + ebufpos, sizeof(Event*)-ebufpos);
+                    if(r < 0) {
+                        break;
+                    }
+                    ebufpos += r;
+                }
+                if(ebufpos == sizeof(Event*)) {
+                    intptr_t *p = (intptr_t*)b;
+                    *(&event) = (Event*)*p;
                     if(event->fn) {
                         if(!event->fn(ev, event) && event->finish) {
                             event->finish(ev, event);
                         }
                     }
-                }               
+                }              
             } else if(event->fn) {
                 int saved_ev = event->events;
                 if(!event->fn(ev, event)) {
@@ -180,7 +195,10 @@
 int event_send(EventHandler *h, Event *event) {
     event->object = 0;
     event->events = 0;
-    ssize_t r = write(h->eventfd, &event, sizeof(Event*));
+    ssize_t r = write(h->eventout, &event, sizeof(Event*));
+    if(r < sizeof(Event*)) {
+        log_ereport(LOG_FAILURE, "failed to send event: %s", strerror(errno));
+    }
     return r > 0 ? 0 : 1;
 }
 

mercurial