diff -up bind-9.5.0b2/lib/isc/unix/socket.c.recv bind-9.5.0b2/lib/isc/unix/socket.c --- bind-9.5.0b2/lib/isc/unix/socket.c.recv 2008-04-10 16:45:33.000000000 +0200 +++ bind-9.5.0b2/lib/isc/unix/socket.c 2008-04-10 17:00:46.000000000 +0200 @@ -261,10 +261,10 @@ static isc_result_t allocate_socket(isc_ static void destroy(isc_socket_t **); static void internal_accept(isc_task_t *, isc_event_t *); static void internal_connect(isc_task_t *, isc_event_t *); -static void internal_recv(isc_task_t *, isc_event_t *); +static void internal_recv(isc_event_t *); static void internal_send(isc_task_t *, isc_event_t *); static void internal_fdwatch_write(isc_task_t *, isc_event_t *); -static void internal_fdwatch_read(isc_task_t *, isc_event_t *); +static void internal_fdwatch_read(isc_event_t *); static void process_cmsg(isc_socket_t *, struct msghdr *, isc_socketevent_t *); static void build_msghdr_send(isc_socket_t *, isc_socketevent_t *, struct msghdr *, struct iovec *, size_t *); @@ -1830,7 +1830,7 @@ isc_socket_detach(isc_socket_t **socketp * * The socket and manager must be locked before calling this function. */ -static void +static isc_boolean_t dispatch_recv(isc_socket_t *sock) { intev_t *iev; isc_socketevent_t *ev; @@ -1841,7 +1841,7 @@ dispatch_recv(isc_socket_t *sock) { if (sock->type != isc_sockettype_fdwatch) { ev = ISC_LIST_HEAD(sock->recv_list); if (ev == NULL) - return; + return ISC_FALSE; socket_log(sock, NULL, EVENT, NULL, 0, 0, "dispatch_recv: event %p -> task %p", ev, ev->ev_sender); @@ -1855,13 +1855,16 @@ dispatch_recv(isc_socket_t *sock) { sock->references++; iev->ev_sender = sock; + iev->ev_arg = sock; if (sock->type == isc_sockettype_fdwatch) - iev->ev_action = internal_fdwatch_read; + internal_fdwatch_read (iev); else - iev->ev_action = internal_recv; - iev->ev_arg = sock; + internal_recv (iev); - isc_task_send(sender, (isc_event_t **)&iev); + if (sock->references == 0) + return ISC_TRUE; + + return ISC_FALSE; } static void @@ -2228,7 +2231,7 @@ internal_accept(isc_task_t *me, isc_even } static void -internal_recv(isc_task_t *me, isc_event_t *ev) { +internal_recv(isc_event_t *ev) { isc_socketevent_t *dev; isc_socket_t *sock; @@ -2237,21 +2240,13 @@ internal_recv(isc_task_t *me, isc_event_ sock = ev->ev_sender; INSIST(VALID_SOCKET(sock)); - LOCK(&sock->lock); - socket_log(sock, NULL, IOEVENT, - isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_INTERNALRECV, - "internal_recv: task %p got event %p", me, ev); - INSIST(sock->pending_recv == 1); sock->pending_recv = 0; INSIST(sock->references > 0); sock->references--; /* the internal event is done with this socket */ - if (sock->references == 0) { - UNLOCK(&sock->lock); - destroy(&sock); + if (sock->references == 0) return; - } /* * Try to do as much I/O as possible on this socket. There are no @@ -2289,7 +2284,6 @@ internal_recv(isc_task_t *me, isc_event_ if (!ISC_LIST_EMPTY(sock->recv_list)) select_poke(sock->manager, sock->fd, SELECT_POKE_READ); - UNLOCK(&sock->lock); } static void @@ -2388,7 +2382,7 @@ internal_fdwatch_write(isc_task_t *me, i } static void -internal_fdwatch_read(isc_task_t *me, isc_event_t *ev) { +internal_fdwatch_read(isc_event_t *ev) { isc_socket_t *sock; int more_data; @@ -2400,31 +2394,19 @@ internal_fdwatch_read(isc_task_t *me, is sock = (isc_socket_t *)ev->ev_sender; INSIST(VALID_SOCKET(sock)); - LOCK(&sock->lock); - socket_log(sock, NULL, IOEVENT, - isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_INTERNALRECV, - "internal_fdwatch_read: task %p got event %p", me, ev); - INSIST(sock->pending_recv == 1); - UNLOCK(&sock->lock); - more_data = (sock->fdwatchcb)(me, sock, sock->fdwatcharg); - LOCK(&sock->lock); + INSIST(0); /* We should not be here */ sock->pending_recv = 0; INSIST(sock->references > 0); sock->references--; /* the internal event is done with this socket */ - if (sock->references == 0) { - UNLOCK(&sock->lock); - destroy(&sock); + if (sock->references == 0) return; - } if (more_data) select_poke(sock->manager, sock->fd, SELECT_POKE_READ); - - UNLOCK(&sock->lock); } static void @@ -2434,6 +2416,7 @@ process_fds(isc_socketmgr_t *manager, in int i; isc_socket_t *sock; isc_boolean_t unlock_sock; + isc_boolean_t destroy_sock; REQUIRE(maxfd <= (int)FD_SETSIZE); @@ -2462,6 +2445,7 @@ process_fds(isc_socketmgr_t *manager, in sock = manager->fds[i]; unlock_sock = ISC_FALSE; + destroy_sock = ISC_FALSE; if (FD_ISSET(i, readfds)) { if (sock == NULL) { FD_CLR(i, &manager->read_fds); @@ -2473,7 +2457,7 @@ process_fds(isc_socketmgr_t *manager, in if (sock->listener) dispatch_accept(sock); else - dispatch_recv(sock); + destroy_sock = dispatch_recv(sock); } FD_CLR(i, &manager->read_fds); } @@ -2497,6 +2481,8 @@ process_fds(isc_socketmgr_t *manager, in } if (unlock_sock) UNLOCK(&sock->lock); + if (destroy_sock) + destroy(&sock); } }