diff -r 391ccd490d97 -r 6a145e13d933 src/server/daemon/event_linux.c --- 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;ieventfd, &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; }