--- a/src/server/daemon/event_linux.c Tue Dec 27 14:02:28 2016 +0100 +++ b/src/server/daemon/event_linux.c Tue Dec 27 17:19:00 2016 +0100 @@ -97,24 +97,49 @@ /* wait for events */ int ret = epoll_wait(ep, events, 16, 100000); if(ret == -1 && errno != EINTR) { - /* TODO: check for error */ - perror("epoll_wait"); + log_ereport(LOG_FAILURE, "epoll_wait failed: %s", strerror(errno)); continue; } for(int i=0;i<ret;i++) { event_t *event = events[i].data.ptr; if(event->fn) { + int saved_ev = event->poll; if(!event->fn(ev, event)) { // event fn returned 0 -> remove event from epoll if(epoll_ctl(ep, EPOLL_CTL_DEL, event->object, NULL)) { - perror("epoll_ctl"); + log_ereport( + LOG_FAILURE, + "epoll_ctl failed: %s", + strerror(errno)); } // if set, execute event->finish if(event->finish) { event->finish(ev, event); } + } else { + if(saved_ev != event->poll) { + // event type changed + struct epoll_event epev; + epev.events = EPOLLET; + epev.data.ptr = event; + + // adjust epoll events + if((event->poll & EVENT_POLLIN) == EVENT_POLLIN) { + epev.events |= EPOLLIN; + } + if((event->poll & EVENT_POLLOUT) == EVENT_POLLOUT) { + epev.events |= EPOLLOUT; + } + + if(epoll_ctl(ep, EPOLL_CTL_MOD, event->object, NULL)) { + log_ereport( + LOG_FAILURE, + "epoll_wait failed: %s", + strerror(errno)); + } + } } } } @@ -136,23 +161,25 @@ int ev_pollin(event_handler_t *h, int fd, event_t *event) { event->object = (intptr_t)fd; + event->poll = EVENT_POLLIN; struct epoll_event epev; - epev.events = EPOLLIN | EPOLLET; /* input event, edge triggered */ + epev.events = EPOLLIN | EPOLLET; // input event, edge triggered epev.data.ptr = event; return epoll_ctl(ev_get_port(h), EPOLL_CTL_ADD, fd, &epev); } int ev_pollout(event_handler_t *h, int fd, event_t *event) { event->object = (intptr_t)fd; + event->poll = EVENT_POLLOUT; struct epoll_event epev; - epev.events = EPOLLOUT | EPOLLET; /* input event, edge triggered */ + epev.events = EPOLLOUT | EPOLLET; // input event, edge triggered epev.data.ptr = event; return epoll_ctl(ev_get_port(h), EPOLL_CTL_ADD, fd, &epev); } int evt_send(event_handler_t *h, event_t *event) { event->object = 0; - // TODO: implement using threadpool + // TODO: implement using threadpool or eventfd fprintf(stderr, "Warning: evt_send not implemented\n"); return 0; }