From 9f1ee24abb44d3cf7b2d9c76f68b76ca7265fae2 Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Fri, 17 Apr 2009 09:01:52 +0000 Subject: [PATCH] faster fix for winsock handler. git-svn-id: file:///svn/unbound/trunk@1605 be551aaa-1e26-0410-a405-d3ace91eadb9 --- doc/Changelog | 1 + util/winsock_event.c | 27 ++++++++++++++------------- util/winsock_event.h | 3 ++- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/doc/Changelog b/doc/Changelog index d2fbb0a7c..d62b78c20 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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 diff --git a/util/winsock_event.c b/util/winsock_event.c index bc214863f..4e5a9f2b7 100644 --- a/util/winsock_event.c +++ b/util/winsock_event.c @@ -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; imax; i++) { - if(base->items[i] == e) - return i; + for(i=0; iitems[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; iwaitfor[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", diff --git a/util/winsock_event.h b/util/winsock_event.h index 340eb2ec0..088283e12 100644 --- a/util/winsock_event.h +++ b/util/winsock_event.h @@ -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]; }; /** -- 2.47.3