Windows winsock handler problem fixup.

git-svn-id: file:///svn/unbound/trunk@1602 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2009-04-16 14:54:58 +00:00
parent f32d07786a
commit 9ea5b16bae
3 changed files with 33 additions and 4 deletions

View file

@ -2,6 +2,7 @@
- winsock event handler exit very quickly on signal, even if - winsock event handler exit very quickly on signal, even if
under heavy load. under heavy load.
- iana portlist updated. - iana portlist updated.
- fixup windows winsock handler reentrant problem.
14 April 2009: Wouter 14 April 2009: Wouter
- bug #245: fix munin plugin, perform cleanup of stale lockfiles. - bug #245: fix munin plugin, perform cleanup of stale lockfiles.

View file

@ -95,6 +95,18 @@ find_fd(struct event_base* base, int fd)
return -1; 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) void *event_init(uint32_t* time_secs, struct timeval* time_tv)
{ {
struct event_base* base = (struct event_base*)malloc( struct event_base* base = (struct event_base*)malloc(
@ -281,10 +293,15 @@ static int handle_select(struct event_base* base, struct timeval* wait)
/* callbacks */ /* callbacks */
if(base->tcp_stickies) if(base->tcp_stickies)
startidx = 0; /* process all events, some are sticky */ 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"); verbose(VERB_CLIENT, "winsock_event signals");
for(i=startidx; i<numwait; i++) { for(i=startidx; i<numwait; i++) {
if(find_entry(base, eventlist[i]) == -1)
continue; /* event was deleted */
if(eventlist[i]->is_signal) { if(eventlist[i]->is_signal) {
eventlist[i]->just_checked = 0;
handle_signal(eventlist[i]); 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++) { for(i=startidx; i<numwait; i++) {
short bits = 0; short bits = 0;
/* eventlist[i] fired */ /* eventlist[i] fired */
if(eventlist[i]->is_signal) { /* see if eventlist[i] is still valid and just checked from
/* not a network event at all */ * WSAWaitForEvents */
continue; 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, if(WSAEnumNetworkEvents(eventlist[i]->ev_fd,
waitfor[i], /* reset the event handle */ waitfor[i], /* reset the event handle */
/*NULL,*/ /* do not 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; ev->ev_callback = cb;
fptr_ok(fptr_whitelist_event(ev->ev_callback)); fptr_ok(fptr_whitelist_event(ev->ev_callback));
ev->ev_arg = arg; ev->ev_arg = arg;
ev->just_checked = 0;
ev->added = 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->ev_base->items[ev->idx] = ev;
ev->is_tcp = 0; ev->is_tcp = 0;
ev->is_signal = 0; ev->is_signal = 0;
ev->just_checked = 0;
if((ev->ev_events&(EV_READ|EV_WRITE)) && ev->ev_fd != -1) { if((ev->ev_events&(EV_READ|EV_WRITE)) && ev->ev_fd != -1) {
BOOL b=0; BOOL b=0;
@ -567,6 +592,7 @@ int event_del(struct event *ev)
log_err("WSACloseEvent failed: %s", log_err("WSACloseEvent failed: %s",
wsa_strerror(WSAGetLastError())); wsa_strerror(WSAGetLastError()));
} }
ev->just_checked = 0;
ev->added = 0; ev->added = 0;
return 0; return 0;
} }

View file

@ -188,6 +188,8 @@ struct event {
* User created and user closed WSAEvent. Only signaled/unsigneled, * User created and user closed WSAEvent. Only signaled/unsigneled,
* no read/write/distinctions needed. */ * no read/write/distinctions needed. */
int is_signal; int is_signal;
/** used during callbacks to see which events were just checked */
int just_checked;
}; };
/** create event base */ /** create event base */