Sfoglia il codice sorgente

BReactor: optimize event loop

ambrop7 15 anni fa
parent
commit
feebd816c4
1 ha cambiato i file con 88 aggiunte e 109 eliminazioni
  1. 88 109
      system/BReactor.c

+ 88 - 109
system/BReactor.c

@@ -53,13 +53,6 @@ typedef int btimeout_t;
 #define WAITRES_TIMED_OUT(_res) ((_res) == 0)
 #endif
 
-static void dispatch_jobs (BReactor *bsys)
-{
-    while (!bsys->exiting && BPendingGroup_HasJobs(&bsys->pending_jobs)) {
-        BPendingGroup_ExecuteJob(&bsys->pending_jobs);
-    }
-}
-
 static int timer_comparator (void *user, btime_t *val1, btime_t *val2)
 {
     if (*val1 < *val2) {
@@ -140,55 +133,7 @@ static void move_first_timers (BReactor *bsys)
     }
 }
 
-static void dispatch_timers (BReactor *bsys)
-{
-    // call event hendlers for expired timers
-    // Handler functions are free to remove any timer, and if a pending
-    // expired timer is removed, it will not be reported.
-    
-    LinkedList2Node *list_node;
-    while (!bsys->exiting && (list_node = LinkedList2_GetFirst(&bsys->timers_expired_list))) {
-        BTimer *timer = UPPER_OBJECT(list_node, BTimer, list_node);
-        ASSERT(timer->active)
-        ASSERT(timer->expired)
-        
-        // remove from expired list
-        LinkedList2_Remove(&bsys->timers_expired_list, &timer->list_node);
-        
-        // set inactive
-        timer->active = 0;
-        
-        // call handler
-        BLog(BLOG_DEBUG, "Dispatching timer");
-        timer->handler(timer->handler_pointer);
-        
-        // dispatch jobs
-        dispatch_jobs(bsys);
-    }
-}
-
-#ifdef BADVPN_USE_WINAPI
-
-static void dispatch_io (BReactor *bsys)
-{
-    if (!bsys->exiting && bsys->returned_object) {
-        BHandle *bh = bsys->returned_object;
-        bsys->returned_object = NULL;
-        ASSERT(bh->active)
-        ASSERT(bh->position >= 0 && bh->position < bsys->enabled_num)
-        ASSERT(bh == bsys->enabled_objects[bh->position])
-        ASSERT(bh->h == bsys->enabled_handles[bh->position])
-        
-        // call handler
-        BLog(BLOG_DEBUG, "Dispatching handle");
-        bh->handler(bh->user);
-        
-        // dispatch jobs
-        dispatch_jobs(bsys);
-    }
-}
-
-#else
+#ifndef BADVPN_USE_WINAPI
 
 static void set_fd_pointers (BReactor *bsys)
 {
@@ -205,52 +150,6 @@ static void set_fd_pointers (BReactor *bsys)
     }
 }
 
-static void dispatch_io (BReactor *bsys)
-{
-    while (!bsys->exiting && bsys->epoll_results_pos < bsys->epoll_results_num) {
-        // grab event
-        struct epoll_event *event = &bsys->epoll_results[bsys->epoll_results_pos];
-        bsys->epoll_results_pos++;
-        
-        // check if the BFileDescriptor was removed
-        if (!event->data.ptr) {
-            continue;
-        }
-        
-        // get BFileDescriptor
-        BFileDescriptor *bfd = (BFileDescriptor *)event->data.ptr;
-        ASSERT(bfd->active)
-        ASSERT(bfd->epoll_returned_ptr == (BFileDescriptor **)&event->data.ptr)
-        
-        // zero pointer to the epoll entry
-        bfd->epoll_returned_ptr = NULL;
-        
-        // calculate events to report
-        int events = 0;
-        if ((bfd->waitEvents&BREACTOR_READ) && (event->events&EPOLLIN)) {
-            events |= BREACTOR_READ;
-        }
-        if ((bfd->waitEvents&BREACTOR_WRITE) && (event->events&EPOLLOUT)) {
-            events |= BREACTOR_WRITE;
-        }
-        if ((event->events&EPOLLERR) || (event->events&EPOLLHUP)) {
-            events |= BREACTOR_ERROR;
-        }
-        
-        if (!events) {
-            BLog(BLOG_ERROR, "no events detected?");
-            continue;
-        }
-        
-        // call handler
-        BLog(BLOG_DEBUG, "Dispatching file descriptor");
-        bfd->handler(bfd->user, events);
-        
-        // dispatch jobs
-        dispatch_jobs(bsys);
-    }
-}
-
 #endif
 
 static void wait_for_events (BReactor *bsys)
@@ -501,16 +400,96 @@ void BReactor_Free (BReactor *bsys)
 int BReactor_Exec (BReactor *bsys)
 {
     BLog(BLOG_DEBUG, "Entering event loop");
-
-    while (1) {
-        dispatch_jobs(bsys);
-        dispatch_timers(bsys);
-        dispatch_io(bsys);
+    
+    while (!bsys->exiting) {
+        // dispatch job
+        if (BPendingGroup_HasJobs(&bsys->pending_jobs)) {
+            BPendingGroup_ExecuteJob(&bsys->pending_jobs);
+            continue;
+        }
         
-        if (bsys->exiting) {
-            break;
+        // dispatch timer
+        LinkedList2Node *list_node = LinkedList2_GetFirst(&bsys->timers_expired_list);
+        if (list_node) {
+            BTimer *timer = UPPER_OBJECT(list_node, BTimer, list_node);
+            ASSERT(timer->active)
+            ASSERT(timer->expired)
+            
+            // remove from expired list
+            LinkedList2_Remove(&bsys->timers_expired_list, &timer->list_node);
+            
+            // set inactive
+            timer->active = 0;
+            
+            // call handler
+            BLog(BLOG_DEBUG, "Dispatching timer");
+            timer->handler(timer->handler_pointer);
+            continue;
         }
         
+        #ifdef BADVPN_USE_WINAPI
+        
+        // dispatch handle
+        if (bsys->returned_object) {
+            BHandle *bh = bsys->returned_object;
+            bsys->returned_object = NULL;
+            ASSERT(bh->active)
+            ASSERT(bh->position >= 0 && bh->position < bsys->enabled_num)
+            ASSERT(bh == bsys->enabled_objects[bh->position])
+            ASSERT(bh->h == bsys->enabled_handles[bh->position])
+            
+            // call handler
+            BLog(BLOG_DEBUG, "Dispatching handle");
+            bh->handler(bh->user);
+            continue;
+        }
+        
+        #else
+        
+        // dispatch file descriptor
+        if (bsys->epoll_results_pos < bsys->epoll_results_num) {
+            // grab event
+            struct epoll_event *event = &bsys->epoll_results[bsys->epoll_results_pos];
+            bsys->epoll_results_pos++;
+            
+            // check if the BFileDescriptor was removed
+            if (!event->data.ptr) {
+                continue;
+            }
+            
+            // get BFileDescriptor
+            BFileDescriptor *bfd = (BFileDescriptor *)event->data.ptr;
+            ASSERT(bfd->active)
+            ASSERT(bfd->epoll_returned_ptr == (BFileDescriptor **)&event->data.ptr)
+            
+            // zero pointer to the epoll entry
+            bfd->epoll_returned_ptr = NULL;
+            
+            // calculate events to report
+            int events = 0;
+            if ((bfd->waitEvents&BREACTOR_READ) && (event->events&EPOLLIN)) {
+                events |= BREACTOR_READ;
+            }
+            if ((bfd->waitEvents&BREACTOR_WRITE) && (event->events&EPOLLOUT)) {
+                events |= BREACTOR_WRITE;
+            }
+            if ((event->events&EPOLLERR) || (event->events&EPOLLHUP)) {
+                events |= BREACTOR_ERROR;
+            }
+            
+            if (!events) {
+                BLog(BLOG_ERROR, "no events detected?");
+                continue;
+            }
+            
+            // call handler
+            BLog(BLOG_DEBUG, "Dispatching file descriptor");
+            bfd->handler(bfd->user, events);
+            continue;
+        }
+        
+        #endif
+        
         wait_for_events(bsys);
     }