]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Windows winsock handler problem fixup.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 16 Apr 2009 14:54:58 +0000 (14:54 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 16 Apr 2009 14:54:58 +0000 (14:54 +0000)
git-svn-id: file:///svn/unbound/trunk@1602 be551aaa-1e26-0410-a405-d3ace91eadb9

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

index b78f99690be89802231435655ea00d289e02fbdc..f469428e3d4228a97cd2da64c2fcf89ec1112326 100644 (file)
@@ -2,6 +2,7 @@
        - winsock event handler exit very quickly on signal, even if
          under heavy load.
        - iana portlist updated.
+       - fixup windows winsock handler reentrant problem.
 
 14 April 2009: Wouter
        - bug #245: fix munin plugin, perform cleanup of stale lockfiles.
index 83ee8ebc9727447917226d36ca1f095264e24e34..55cc2314350e3cc41b0b233166d1d5a6ddbbefab 100644 (file)
@@ -95,6 +95,18 @@ find_fd(struct event_base* base, int fd)
        return -1;
 }
 
+/** Find ptr in base array */
+static int
+find_entry(struct event_base* base, struct event* e)
+{
+       int i;
+       for(i=0; i<base->max; i++) {
+               if(base->items[i] == e)
+                       return i;
+       }
+       return -1;
+}
+
 void *event_init(uint32_t* time_secs, struct timeval* time_tv)
 {
         struct event_base* base = (struct event_base*)malloc(
@@ -281,10 +293,15 @@ static int handle_select(struct event_base* base, struct timeval* wait)
        /* callbacks */
        if(base->tcp_stickies)
                startidx = 0; /* process all events, some are sticky */
+       for(i=startidx; i<numwait; i++) {
+               eventlist[i]->just_checked = 1;
 
        verbose(VERB_CLIENT, "winsock_event signals");
        for(i=startidx; i<numwait; i++) {
+               if(find_entry(base, eventlist[i]) == -1)
+                       continue; /* event was deleted */
                if(eventlist[i]->is_signal) {
+                       eventlist[i]->just_checked = 0;
                        handle_signal(eventlist[i]);
                }
        }
@@ -296,10 +313,16 @@ static int handle_select(struct event_base* base, struct timeval* wait)
        for(i=startidx; i<numwait; i++) {
                short bits = 0;
                /* eventlist[i] fired */
-               if(eventlist[i]->is_signal) {
-                       /* not a network event at all */
-                       continue;
-               }
+               /* 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(!eventlist[i]->just_checked)
+                       continue; /* added by other callback */
+               if(eventlist[i]->is_signal)
+                       continue; /* not a network event at all */
+               eventlist[i]->just_checked = 0;
+
                if(WSAEnumNetworkEvents(eventlist[i]->ev_fd, 
                        waitfor[i], /* reset the event handle */
                        /*NULL,*/ /* do not reset the event handle */
@@ -448,6 +471,7 @@ void event_set(struct event *ev, int fd, short bits,
         ev->ev_callback = cb;
         fptr_ok(fptr_whitelist_event(ev->ev_callback));
         ev->ev_arg = arg;
+       ev->just_checked = 0;
         ev->added = 0;
 }
 
@@ -477,6 +501,7 @@ int event_add(struct event *ev, struct timeval *tv)
        ev->ev_base->items[ev->idx] = ev;
        ev->is_tcp = 0;
        ev->is_signal = 0;
+       ev->just_checked = 0;
 
         if((ev->ev_events&(EV_READ|EV_WRITE)) && ev->ev_fd != -1) {
                BOOL b=0;
@@ -567,6 +592,7 @@ int event_del(struct event *ev)
                        log_err("WSACloseEvent failed: %s",
                                wsa_strerror(WSAGetLastError()));
        }
+       ev->just_checked = 0;
         ev->added = 0;
         return 0;
 }
index 3a3c62d2c81427f194624ec407b0b35c19c265b4..340eb2ec048475461f01599fe9ccd38eccb129ae 100644 (file)
@@ -188,6 +188,8 @@ struct event {
         * User created and user closed WSAEvent. Only signaled/unsigneled,
         * no read/write/distinctions needed. */
        int is_signal;
+       /** used during callbacks to see which events were just checked */
+       int just_checked;
 };
 
 /** create event base */