[IOMultiplexer] Added asynchronous DNS Lookups
[IOMultiplexer.git] / src / IOEngine_epoll.c
index 19c62272518c29804a26a41221577afba0b2d0eb..e115c003b155da6206d8aa4dbdbc287d654a8754 100644 (file)
@@ -33,36 +33,44 @@ static int engine_epoll_init() {
     return 1;
 }
 
-static void engine_epoll_add(struct IODescriptor *iofd) {
-    if(iofd->type == IOTYPE_TIMER) return;
+static void engine_epoll_add(struct IOLowlevelDescriptor *iold) {
+    if(iold->fd != -1) return;
     //add descriptor to the epoll queue
     struct epoll_event evt;
     int res;
 
-    evt.events = EPOLLHUP | EPOLLIN | (iohandler_wants_writes(iofd) ? EPOLLOUT : 0);
-    evt.data.ptr = iofd;
-    res = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, iofd->fd, &evt);
+    evt.events = EPOLLHUP | ((iold->flags & IOFLAGS_WANT_READ) ? EPOLLIN : 0) | ((iold->flags & IOFLAGS_WANT_WRITE) ? EPOLLOUT : 0);
+    evt.data.ptr = iold;
+    res = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, iold->fd, &evt);
     if(res < 0) {
-        iohandler_log(IOLOG_ERROR, "could not add IODescriptor %d to epoll queue. (returned: %d)", iofd->fd, res);
+        iohandler_log(IOLOG_ERROR, "could not add IOLowlevelDescriptor %d to epoll queue. (returned: %d)", iold->fd, res);
     }
 }
 
-static void engine_epoll_remove(struct IODescriptor *iofd) {
-    if(iofd->type == IOTYPE_TIMER) return;
+static void engine_epoll_remove(struct IOLowlevelDescriptor *iold) {
+    if(iold->fd != -1) return;
     struct epoll_event evt;
-    epoll_ctl(epoll_fd, EPOLL_CTL_DEL, iofd->fd, &evt);
+    epoll_ctl(epoll_fd, EPOLL_CTL_DEL, iold->fd, &evt);
 }
 
-static void engine_epoll_update(struct IODescriptor *iofd) {
-    if(iofd->type == IOTYPE_TIMER) return;
+static void engine_epoll_update(struct IOLowlevelDescriptor *iold) {
+    if(iold->fd != -1) return;
+    struct IODescriptor *iofd;
+    if((iofd = IOLOWLEVEL_GET_IOFD(iold))) {
+        if(iofd->state == IO_CLOSED) {
+            engine_epoll_remove(iold);
+            return;
+        }
+    }
+    
     struct epoll_event evt;
     int res;
 
-    evt.events = EPOLLHUP | EPOLLIN | (iohandler_wants_writes(iofd) ? EPOLLOUT : 0);
-    evt.data.ptr = iofd;
-    res = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, iofd->fd, &evt);
+    evt.events = EPOLLHUP | ((iold->flags & IOFLAGS_WANT_READ) ? EPOLLIN : 0) | ((iold->flags & IOFLAGS_WANT_WRITE) ? EPOLLOUT : 0);
+    evt.data.ptr = iold;
+    res = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, iold->fd, &evt);
     if(res < 0) {
-        iohandler_log(IOLOG_ERROR, "could not update IODescriptor %d in epoll queue. (returned: %d)", iofd->fd, res);
+        iohandler_log(IOLOG_ERROR, "could not update IOLowlevelDescriptor %d in epoll queue. (returned: %d)", iold->fd, res);
     }
 }
 
@@ -72,6 +80,7 @@ static void engine_epoll_loop(struct timeval *timeout) {
     int msec;
     int events;
     int epoll_result;
+    struct IOLowlevelDescriptor *iold;
     
     gettimeofday(&now, NULL);
     
@@ -79,8 +88,14 @@ static void engine_epoll_loop(struct timeval *timeout) {
         tdiff.tv_sec = timer_priority->timeout.tv_sec - now.tv_sec;
         tdiff.tv_usec = timer_priority->timeout.tv_usec - now.tv_usec;
         if(tdiff.tv_sec < 0 || (tdiff.tv_sec == 0 && tdiff.tv_usec <= 0)) {
-            iohandler_events(timer_priority, 0, 0);
-            iohandler_close(timer_priority); //also sets timer_priority to the next timed element
+            if(timer_priority->constant_timeout) {
+                tdiff.tv_sec = 0;
+                iohandler_set_timeout(timer_priority, &tdiff);
+                iohandler_events(timer_priority, 0, 0);
+            } else {
+                iohandler_events(timer_priority, 0, 0);
+                iohandler_close(timer_priority); //also sets timer_priority to the next timed element
+            }
             continue;
         } else if(tdiff.tv_usec < 0) {
             tdiff.tv_sec--;
@@ -107,7 +122,11 @@ static void engine_epoll_loop(struct timeval *timeout) {
         int i;
         for(i = 0; i < epoll_result; i++) {
             events = evts[i].events;
-            iohandler_events(evts[i].data.ptr, (events & (EPOLLIN | EPOLLHUP)), (events & EPOLLOUT));
+            iold = evts[i].data.ptr;
+            if(iold->flags & IOFLAGS_HAVE_IOFD)
+                iohandler_events(iold->data.iofd, (events & (EPOLLIN | EPOLLHUP)), (events & EPOLLOUT));
+            else
+                iold->data.callback(iold, (events & (EPOLLIN | EPOLLHUP)), (events & EPOLLOUT));
         }
     }
     
@@ -116,8 +135,14 @@ static void engine_epoll_loop(struct timeval *timeout) {
         tdiff.tv_sec = timer_priority->timeout.tv_sec - now.tv_sec;
         tdiff.tv_usec = timer_priority->timeout.tv_usec - now.tv_usec;
         if(tdiff.tv_sec < 0 || (tdiff.tv_sec == 0 && tdiff.tv_usec <= 0)) {
-            iohandler_events(timer_priority, 0, 0);
-            iohandler_close(timer_priority); //also sets timer_priority to the next timed element
+            if(timer_priority->constant_timeout) {
+                tdiff.tv_sec = 0;
+                iohandler_set_timeout(timer_priority, &tdiff);
+                iohandler_events(timer_priority, 0, 0);
+            } else {
+                iohandler_events(timer_priority, 0, 0);
+                iohandler_close(timer_priority); //also sets timer_priority to the next timed element
+            }
             continue;
         }
         break;