]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
faster fix for winsock handler.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 17 Apr 2009 09:01:52 +0000 (09:01 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 17 Apr 2009 09:01:52 +0000 (09:01 +0000)
git-svn-id: file:///svn/unbound/trunk@1605 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
util/winsock_event.c
util/winsock_event.h

index d2fbb0a7c9807597948ace22fc96e49b69c5595c..d62b78c2033465960a6817af6ac38b3b672c85a0 100644 (file)
@@ -2,6 +2,7 @@
        - Fix reentrant in minievent handler for unix. Could have resulted
          in spurious event callbacks.
        - timers do not take up a fd slot for winsock handler.
+       - faster fix for winsock reentrant check.
 
 16 April 2009: Wouter
        - winsock event handler exit very quickly on signal, even if
index bc214863fbbb1808919a1557aca6a3e088690c06..4e5a9f2b7016399d605c6650782d04ab9f70c547 100644 (file)
@@ -97,14 +97,13 @@ find_fd(struct event_base* base, int fd)
 
 /** Find ptr in base array */
 static int
-find_entry(struct event_base* base, struct event* e)
+zero_waitfor(WSAEVENT waitfor[], WSAEVENT x)
 {
        int i;
-       for(i=0; i<base->max; i++) {
-               if(base->items[i] == e)
-                       return i;
+       for(i=0; i<WSK_MAX_ITEMS; i++) {
+               if(waitfor[i] == x)
+                       waitfor[i] = 0;
        }
-       return -1;
 }
 
 void *event_init(uint32_t* time_secs, struct timeval* time_tv)
@@ -226,7 +225,6 @@ static int handle_select(struct event_base* base, struct timeval* wait)
 {
        DWORD timeout = 0; /* in milliseconds */        
        DWORD ret;
-       WSAEVENT waitfor[WSK_MAX_ITEMS];
        struct event* eventlist[WSK_MAX_ITEMS];
        WSANETWORKEVENTS netev;
        int i, numwait = 0, startidx = 0, was_timeout = 0;
@@ -253,7 +251,9 @@ static int handle_select(struct event_base* base, struct timeval* wait)
                if(base->items[i]->ev_fd == -1 && !base->items[i]->is_signal)
                        continue; /* skip timer only events */
                eventlist[numwait] = base->items[i];
-               waitfor[numwait++] = base->items[i]->hEvent;
+               base->waitfor[numwait++] = base->items[i]->hEvent;
+               if(numwait == WSK_MAX_ITEMS)
+                       break; /* sanity check */
        }
        log_assert(numwait <= WSA_MAXIMUM_WAIT_EVENTS);
        verbose(VERB_CLIENT, "winsock_event bmax=%d numwait=%d wait=%x "
@@ -267,7 +267,7 @@ static int handle_select(struct event_base* base, struct timeval* wait)
                }
                was_timeout = 1;
        } else {
-               ret = WSAWaitForMultipleEvents(numwait, waitfor,
+               ret = WSAWaitForMultipleEvents(numwait, base->waitfor,
                        0 /* do not wait for all, just one will do */,
                        wait?timeout:WSA_INFINITE,
                        0); /* we are not alertable (IO completion events) */
@@ -298,8 +298,8 @@ static int handle_select(struct event_base* base, struct timeval* wait)
 
        verbose(VERB_CLIENT, "winsock_event signals");
        for(i=startidx; i<numwait; i++) {
-               if(find_entry(base, eventlist[i]) == -1)
-                       continue; /* event was deleted */
+               if(!base->waitfor[i])
+                       continue; /* was deleted */
                if(eventlist[i]->is_signal) {
                        eventlist[i]->just_checked = 0;
                        handle_signal(eventlist[i]);
@@ -315,8 +315,8 @@ static int handle_select(struct event_base* base, struct timeval* wait)
                /* eventlist[i] fired */
                /* see if eventlist[i] is still valid and just checked from
                 * WSAWaitForEvents */
-               if(find_entry(base, eventlist[i]) == -1)
-                       continue; /* does not exist anymore */
+               if(!base->waitfor[i])
+                       continue; /* was deleted */
                if(!eventlist[i]->just_checked)
                        continue; /* added by other callback */
                if(eventlist[i]->is_signal)
@@ -324,7 +324,7 @@ static int handle_select(struct event_base* base, struct timeval* wait)
                eventlist[i]->just_checked = 0;
 
                if(WSAEnumNetworkEvents(eventlist[i]->ev_fd, 
-                       waitfor[i], /* reset the event handle */
+                       base->waitfor[i], /* reset the event handle */
                        /*NULL,*/ /* do not reset the event handle */
                        &netev) != 0) {
                        log_err("WSAEnumNetworkEvents failed: %s", 
@@ -588,6 +588,7 @@ int event_del(struct event *ev)
                ev->ev_base->max--;
                if(ev->idx < ev->ev_base->max)
                        ev->ev_base->items[ev->idx]->idx = ev->idx;
+               zero_waitfor(base->waitfor, ev->hEvent);
 
                if(WSAEventSelect(ev->ev_fd, ev->hEvent, 0) != 0)
                        log_err("WSAEventSelect(disable) failed: %s",
index 340eb2ec048475461f01599fe9ccd38eccb129ae..088283e128aaa0e0408bf2c0222cb23f15a86fd6 100644 (file)
@@ -145,7 +145,8 @@ struct event_base
         * event_add a sudden interest in the event has incepted.
         */
        int tcp_reinvigorated;
-
+       /** The list of events that is currently being processed. */
+       WSAEVENT waitfor[WSK_MAX_ITEMS];
 };
 
 /**