From: Mark Andrews Date: Tue, 28 Aug 2007 00:42:27 +0000 (+0000) Subject: 2220. [bug] win32: Address a race condition in final shutdown of X-Git-Tag: v9.2.9rc1~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=67d9451466a01ffe59ba340573c82038171f8175;p=thirdparty%2Fbind9.git 2220. [bug] win32: Address a race condition in final shutdown of the Windows socket code. [RT #17028] --- diff --git a/CHANGES b/CHANGES index fec6c77c0a3..12f4dde2bf4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +2220. [bug] win32: Address a race condition in final shutdown of + the Windows socket code. [RT #17028] + 2218. [bug] Remove unnecessary REQUIRE from dns_validator_create(). [RT #16976] diff --git a/lib/isc/win32/socket.c b/lib/isc/win32/socket.c index 72f7a7964f4..6cdb1c0b910 100644 --- a/lib/isc/win32/socket.c +++ b/lib/isc/win32/socket.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: socket.c,v 1.5.2.33 2007/06/18 03:30:31 marka Exp $ */ +/* $Id: socket.c,v 1.5.2.34 2007/08/28 00:42:27 marka Exp $ */ /* This code has been rewritten to take advantage of Windows Sockets * I/O Completion Ports and Events. I/O Completion Ports is ONLY @@ -650,10 +650,11 @@ socket_eventlist_add(event_change_t *evchange, sock_event_list *evlist, /* * Note that the eventLock is locked before calling this function. - * All Events and associated sockets are closed here. */ isc_boolean_t -socket_eventlist_delete(event_change_t *evchange, sock_event_list *evlist) { +socket_eventlist_delete(event_change_t *evchange, sock_event_list *evlist, + isc_socketmgr_t *manager) +{ int i; WSAEVENT hEvent; int iEvent = -1; @@ -700,12 +701,16 @@ socket_eventlist_delete(event_change_t *evchange, sock_event_list *evlist) { evchange->sock->pending_send == 0 && evchange->sock->pending_free) { evchange->sock->pending_free = 0; + ISC_LIST_UNLINK(manager->socklist, evchange->sock, link); dofree = ISC_TRUE; } UNLOCK(&evchange->sock->lock); if (dofree) free_socket(&evchange->sock); + if (ISC_LIST_EMPTY(manager->socklist)) + SIGNAL(&manager->shutdown_ok); + evlist->max_event--; evlist->total_events--; @@ -744,7 +749,8 @@ process_eventlist(sock_event_list *evlist, isc_socketmgr_t *manager) { next = ISC_LIST_NEXT(evchange, link); del = ISC_FALSE; if (evchange->action == EVENT_DELETE) { - del = socket_eventlist_delete(evchange, evlist); + del = socket_eventlist_delete(evchange, evlist, + manager); /* * Delete only if this thread's socket list was @@ -1726,8 +1732,8 @@ destroy_socket(isc_socket_t **sockp) { sock->pending_close != 0) { dofree = ISC_FALSE; sock->pending_free = 1; - } - ISC_LIST_UNLINK(manager->socklist, sock, link); + } else + ISC_LIST_UNLINK(manager->socklist, sock, link); UNLOCK(&sock->lock); if (ISC_LIST_EMPTY(manager->socklist)) @@ -2581,8 +2587,15 @@ SocketIoThread(LPVOID ThreadContext) { dofree = ISC_TRUE; } UNLOCK(&sock->lock); - if (dofree) + if (dofree) { + LOCK(&manager->lock); + ISC_LIST_UNLINK(manager->socklist, + sock, link); free_socket(&sock); + if (ISC_LIST_EMPTY(manager->socklist)) + SIGNAL(&manager->shutdown_ok); + UNLOCK(&manager->lock); + } if (lpo != NULL) HeapFree(hHeapHandle, 0, lpo); continue;