mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-29 13:38:26 +00:00
Deactivate the handle before sending the async close callback.
We could have a race between handle closing and processing async callback. Deactivate the handle before issuing the callback - we have the socket referenced anyway so it's not a problem.
This commit is contained in:
parent
2df610a882
commit
01c4c3301e
5
CHANGES
5
CHANGES
@ -1,3 +1,8 @@
|
|||||||
|
5370. [bug] Deactivation of a netmgr handle associated with a
|
||||||
|
socket could be skipped in some circumstances.
|
||||||
|
Fixed by deactivating the netmgr handle before
|
||||||
|
scheduling the asynchronous close routine. [GL #1700]
|
||||||
|
|
||||||
5369. [func] Add the ability to specify whether or not to wait
|
5369. [func] Add the ability to specify whether or not to wait
|
||||||
for nameserver domain names to be looked up, with
|
for nameserver domain names to be looked up, with
|
||||||
a new RPZ modifying directive 'nsdname-wait-recurse'.
|
a new RPZ modifying directive 'nsdname-wait-recurse'.
|
||||||
|
@ -216,6 +216,7 @@ typedef isc__netievent__socket_t isc__netievent_tcpclose_t;
|
|||||||
typedef isc__netievent__socket_t isc__netievent_tcpdnsclose_t;
|
typedef isc__netievent__socket_t isc__netievent_tcpdnsclose_t;
|
||||||
typedef isc__netievent__socket_t isc__netievent_startread_t;
|
typedef isc__netievent__socket_t isc__netievent_startread_t;
|
||||||
typedef isc__netievent__socket_t isc__netievent_pauseread_t;
|
typedef isc__netievent__socket_t isc__netievent_pauseread_t;
|
||||||
|
typedef isc__netievent__socket_t isc__netievent_closecb_t;
|
||||||
|
|
||||||
typedef struct isc__netievent__socket_req {
|
typedef struct isc__netievent__socket_req {
|
||||||
isc__netievent_type type;
|
isc__netievent_type type;
|
||||||
@ -241,8 +242,6 @@ typedef struct isc__netievent__socket_handle {
|
|||||||
isc_nmhandle_t *handle;
|
isc_nmhandle_t *handle;
|
||||||
} isc__netievent__socket_handle_t;
|
} isc__netievent__socket_handle_t;
|
||||||
|
|
||||||
typedef isc__netievent__socket_handle_t isc__netievent_closecb_t;
|
|
||||||
|
|
||||||
typedef struct isc__netievent_udpsend {
|
typedef struct isc__netievent_udpsend {
|
||||||
isc__netievent_type type;
|
isc__netievent_type type;
|
||||||
isc_nmsocket_t *sock;
|
isc_nmsocket_t *sock;
|
||||||
|
@ -1164,7 +1164,15 @@ isc_nmhandle_unref(isc_nmhandle_t *handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The handle is closed. If the socket has a callback configured
|
* Temporarily reference the socket to ensure that it can't
|
||||||
|
* be deleted by another thread while we're deactivating the
|
||||||
|
* handle.
|
||||||
|
*/
|
||||||
|
isc_nmsocket_attach(sock, &tmp);
|
||||||
|
nmhandle_deactivate(sock, handle);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The handle is gone now. If the socket has a callback configured
|
||||||
* for that (e.g., to perform cleanup after request processing),
|
* for that (e.g., to perform cleanup after request processing),
|
||||||
* call it now, or schedule it to run asynchronously.
|
* call it now, or schedule it to run asynchronously.
|
||||||
*/
|
*/
|
||||||
@ -1174,27 +1182,16 @@ isc_nmhandle_unref(isc_nmhandle_t *handle) {
|
|||||||
} else {
|
} else {
|
||||||
isc__netievent_closecb_t *event = isc__nm_get_ievent(
|
isc__netievent_closecb_t *event = isc__nm_get_ievent(
|
||||||
sock->mgr, netievent_closecb);
|
sock->mgr, netievent_closecb);
|
||||||
|
/*
|
||||||
|
* The socket will be finally detached by the closecb
|
||||||
|
* event handler.
|
||||||
|
*/
|
||||||
isc_nmsocket_attach(sock, &event->sock);
|
isc_nmsocket_attach(sock, &event->sock);
|
||||||
event->handle = handle;
|
|
||||||
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||||
(isc__netievent_t *)event);
|
(isc__netievent_t *)event);
|
||||||
|
|
||||||
/*
|
|
||||||
* If we're doing this asynchronously, then the
|
|
||||||
* async event will take care of cleaning up the
|
|
||||||
* handle and closing the socket.
|
|
||||||
*/
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Temporarily reference the socket to ensure that it can't
|
|
||||||
* be deleted by another thread while we're deactivating the
|
|
||||||
* handle.
|
|
||||||
*/
|
|
||||||
isc_nmsocket_attach(sock, &tmp);
|
|
||||||
nmhandle_deactivate(sock, handle);
|
|
||||||
isc_nmsocket_detach(&tmp);
|
isc_nmsocket_detach(&tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1387,8 +1384,6 @@ isc__nm_async_closecb(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||||||
|
|
||||||
UNUSED(worker);
|
UNUSED(worker);
|
||||||
|
|
||||||
nmhandle_deactivate(ievent->sock, ievent->handle);
|
|
||||||
|
|
||||||
ievent->sock->closehandle_cb(ievent->sock);
|
ievent->sock->closehandle_cb(ievent->sock);
|
||||||
isc_nmsocket_detach(&ievent->sock);
|
isc_nmsocket_detach(&ievent->sock);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user