diff --git a/lib/isc/win32/socket.c b/lib/isc/win32/socket.c index cf6ee8baee..37cce8696a 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.41 2005/09/01 02:25:03 marka Exp $ */ +/* $Id: socket.c,v 1.42 2006/01/06 01:32:08 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 @@ -661,6 +661,7 @@ socket_eventlist_delete(event_change_t *evchange, sock_event_list *evlist) { int i; WSAEVENT hEvent; int iEvent = -1; + isc_boolean_t dofree = ISC_FALSE; REQUIRE(evchange != NULL); /* Make sure this is the right thread from which to delete the event */ @@ -693,8 +694,22 @@ socket_eventlist_delete(event_change_t *evchange, sock_event_list *evlist) { /* Cleanup */ WSACloseEvent(hEvent); - if (evchange->fd >= 0) + + LOCK(&evchange->sock->lock); + if (evchange->sock->pending_close) { + evchange->sock->pending_close = 0; closesocket(evchange->fd); + } + if (evchange->sock->pending_recv == 0 && + evchange->sock->pending_send == 0 && + evchange->sock->pending_free) { + evchange->sock->pending_free = 0; + dofree = ISC_TRUE; + } + UNLOCK(&evchange->sock->lock); + if (dofree) + free_socket(&evchange->sock); + evlist->max_event--; evlist->total_events--; @@ -857,14 +872,12 @@ socket_event_delete(isc_socket_t *sock) { REQUIRE(sock != NULL); REQUIRE(sock->hEvent != NULL); - if (sock->hEvent != NULL) { - sock->wait_type = 0; - sock->pending_close = 1; - notify_eventlist(sock, sock->manager, EVENT_DELETE); - sock->hEvent = NULL; - sock->hAlert = NULL; - sock->evthread_id = 0; - } + sock->wait_type = 0; + sock->pending_close = 1; + notify_eventlist(sock, sock->manager, EVENT_DELETE); + sock->hEvent = NULL; + sock->hAlert = NULL; + sock->evthread_id = 0; } /* @@ -878,17 +891,17 @@ void socket_close(isc_socket_t *sock) { REQUIRE(sock != NULL); - sock->pending_close = 1; + + sock->pending_close = 0; if (sock->hEvent != NULL) socket_event_delete(sock); - else { + else closesocket(sock->fd); - } + if (sock->iocp) { sock->iocp = 0; InterlockedDecrement(&iocp_total); } - } /* @@ -1666,7 +1679,7 @@ startio_send(isc_socket_t *sock, isc_socketevent_t *dev, int *nbytes, } dev->result = ISC_R_SUCCESS; status = DOIO_SOFT; -done: + done: return (status); } @@ -1696,7 +1709,8 @@ destroy_socket(isc_socket_t **sockp) { LOCK(&sock->lock); socket_close(sock); - if (sock->pending_recv != 0 || sock->pending_send != 0) { + if (sock->pending_recv != 0 || sock->pending_send != 0 || + sock->pending_close != 0) { dofree = ISC_FALSE; sock->pending_free = 1; } @@ -1893,6 +1907,7 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, result = make_nonblock(sock->fd); if (result != ISC_R_SUCCESS) { + closesocket(sock->fd); free_socket(&sock); return (result); } @@ -2560,8 +2575,11 @@ SocketIoThread(LPVOID ThreadContext) { } if (sock->pending_recv == 0 && sock->pending_send == 0 && - sock->pending_free) + sock->pending_close == 0 && + sock->pending_free) { + sock->pending_free = 0; dofree = ISC_TRUE; + } UNLOCK(&sock->lock); if (dofree) free_socket(&sock);