2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 23:25:38 +00:00

Fix a cancel problem, and use a condition variable rather than a hack

This commit is contained in:
Michael Graff
1999-05-17 22:31:26 +00:00
parent f0ff273b53
commit e89cd0396e

View File

@@ -87,7 +87,7 @@
#define TRACE_MANAGER 0x0020 #define TRACE_MANAGER 0x0020
int trace_level = TRACE_WATCHER | TRACE_MANAGER; int trace_level = TRACE_WATCHER | TRACE_MANAGER;
#define XTRACE(l, a) do { if ((l) & trace_level) printf a } while (0) #define XTRACE(l, a) do { if ((l) & trace_level) printf a; } while (0)
#define XENTER(l, a) do { \ #define XENTER(l, a) do { \
if ((l) & trace_level) \ if ((l) & trace_level) \
printf("ENTER %s\n", (a)); \ printf("ENTER %s\n", (a)); \
@@ -176,6 +176,7 @@ struct isc_socketmgr {
/* Locked by manager lock. */ /* Locked by manager lock. */
unsigned int nsockets; /* sockets managed */ unsigned int nsockets; /* sockets managed */
isc_thread_t watcher; isc_thread_t watcher;
isc_condition_t shutdown_ok;
fd_set read_fds; fd_set read_fds;
fd_set write_fds; fd_set write_fds;
isc_socket_t *fds[FD_SETSIZE]; isc_socket_t *fds[FD_SETSIZE];
@@ -290,7 +291,7 @@ socket_dump(isc_socket_t *sock)
rwiev = ISC_LIST_HEAD(sock->recv_list); rwiev = ISC_LIST_HEAD(sock->recv_list);
while (rwiev != NULL) { while (rwiev != NULL) {
printf("\tintev %p, done_ev %p, task %p, " printf("\tintev %p, done_ev %p, task %p, "
"canceled %d, posted %d", "canceled %d, posted %d\n",
rwiev, rwiev->done_ev, rwiev->task, rwiev->canceled, rwiev, rwiev->done_ev, rwiev->task, rwiev->canceled,
rwiev->posted); rwiev->posted);
rwiev = ISC_LIST_NEXT(rwiev, link); rwiev = ISC_LIST_NEXT(rwiev, link);
@@ -300,7 +301,7 @@ socket_dump(isc_socket_t *sock)
rwiev = ISC_LIST_HEAD(sock->send_list); rwiev = ISC_LIST_HEAD(sock->send_list);
while (rwiev != NULL) { while (rwiev != NULL) {
printf("\tintev %p, done_ev %p, task %p, " printf("\tintev %p, done_ev %p, task %p, "
"canceled %d, posted %d", "canceled %d, posted %d\n",
rwiev, rwiev->done_ev, rwiev->task, rwiev->canceled, rwiev, rwiev->done_ev, rwiev->task, rwiev->canceled,
rwiev->posted); rwiev->posted);
rwiev = ISC_LIST_NEXT(rwiev, link); rwiev = ISC_LIST_NEXT(rwiev, link);
@@ -382,6 +383,8 @@ destroy(isc_socket_t **sockp)
select_poke(sock->manager, sock->fd); select_poke(sock->manager, sock->fd);
manager->nsockets--; manager->nsockets--;
XTRACE(TRACE_MANAGER, ("nsockets == %d\n", manager->nsockets)); XTRACE(TRACE_MANAGER, ("nsockets == %d\n", manager->nsockets));
if (manager->nsockets == 0)
SIGNAL(&manager->shutdown_ok);
/* /*
* XXX should reset manager->maxfd here * XXX should reset manager->maxfd here
@@ -460,6 +463,9 @@ free_socket(isc_socket_t **socketp)
{ {
isc_socket_t *sock = *socketp; isc_socket_t *sock = *socketp;
#ifdef ISC_SOCKET_DEBUG
socket_dump(sock);
#endif
REQUIRE(sock->references == 0); REQUIRE(sock->references == 0);
REQUIRE(VALID_SOCKET(sock)); REQUIRE(VALID_SOCKET(sock));
REQUIRE(!sock->connecting); REQUIRE(!sock->connecting);
@@ -1568,6 +1574,14 @@ isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp)
return (ISC_R_UNEXPECTED); return (ISC_R_UNEXPECTED);
} }
if (isc_condition_init(&manager->shutdown_ok) != ISC_R_SUCCESS) {
(void)isc_mutex_destroy(&manager->lock);
isc_mem_put(mctx, manager, sizeof *manager);
UNEXPECTED_ERROR(__FILE__, __LINE__,
"isc_condition_init() failed");
return (ISC_R_UNEXPECTED);
}
/* /*
* Create the special fds that will be used to wake up the * Create the special fds that will be used to wake up the
* select/poll loop when something internal needs to be done. * select/poll loop when something internal needs to be done.
@@ -1632,16 +1646,13 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp)
XTRACE(TRACE_MANAGER, ("nsockets == %d\n", manager->nsockets)); XTRACE(TRACE_MANAGER, ("nsockets == %d\n", manager->nsockets));
/* /*
* XXX do this right, with a condition variable * Wait for all sockets to be destroyed.
*/ */
while (manager->nsockets != 0) { while (manager->nsockets != 0) {
XTRACE(TRACE_MANAGER, ("nsockets == %d\n", manager->nsockets)); XTRACE(TRACE_MANAGER, ("nsockets == %d\n", manager->nsockets));
UNLOCK(&manager->lock); WAIT(&manager->shutdown_ok, &manager->lock);
sleep(1);
LOCK(&manager->lock);
} }
REQUIRE(manager->nsockets == 0);
UNLOCK(&manager->lock); UNLOCK(&manager->lock);
/* /*
@@ -1667,6 +1678,7 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp)
if (manager->fdstate[i] == CLOSE_PENDING) if (manager->fdstate[i] == CLOSE_PENDING)
close(i); close(i);
(void)isc_condition_destroy(&manager->shutdown_ok);
(void)isc_mutex_destroy(&manager->lock); (void)isc_mutex_destroy(&manager->lock);
manager->magic = 0; manager->magic = 0;
isc_mem_put(manager->mctx, manager, sizeof *manager); isc_mem_put(manager->mctx, manager, sizeof *manager);
@@ -2548,13 +2560,14 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task,
current_task = iev->task; current_task = iev->task;
if (iev->posted) { if (iev->posted) {
if (isc_task_purge(task, sock, if (isc_task_purge(current_task, sock,
ISC_SOCKEVENT_INTRECV) ISC_SOCKEVENT_INTRECV)
== 0) { == 0) {
iev->canceled = ISC_TRUE; iev->canceled = ISC_TRUE;
iev->done_ev = NULL; iev->done_ev = NULL;
} }
} else { } else {
ISC_LIST_DEQUEUE(sock->recv_list, iev, link);
isc_event_free((isc_event_t **)&iev); isc_event_free((isc_event_t **)&iev);
} }
@@ -2603,6 +2616,7 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task,
iev->done_ev = NULL; iev->done_ev = NULL;
} }
} else { } else {
ISC_LIST_DEQUEUE(sock->send_list, iev, link);
isc_event_free((isc_event_t **)&iev); isc_event_free((isc_event_t **)&iev);
} }
@@ -2640,13 +2654,14 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task,
current_task = iev->task; current_task = iev->task;
if (iev->posted) { if (iev->posted) {
if (isc_task_purge(task, sock, if (isc_task_purge(current_task, sock,
ISC_SOCKEVENT_INTACCEPT) ISC_SOCKEVENT_INTACCEPT)
== 0) { == 0) {
iev->canceled = ISC_TRUE; iev->canceled = ISC_TRUE;
iev->done_ev = NULL; iev->done_ev = NULL;
} }
} else { } else {
ISC_LIST_DEQUEUE(sock->accept_list, iev, link);
isc_event_free((isc_event_t **)&iev); isc_event_free((isc_event_t **)&iev);
} }
@@ -2677,6 +2692,9 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task,
} }
} }
/*
* Connecting is not a list.
*/
if (((how & ISC_SOCKCANCEL_CONNECT) == ISC_SOCKCANCEL_CONNECT) if (((how & ISC_SOCKCANCEL_CONNECT) == ISC_SOCKCANCEL_CONNECT)
&& sock->connect_ev != NULL) { && sock->connect_ev != NULL) {
cnintev_t * iev; cnintev_t * iev;
@@ -2689,7 +2707,7 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task,
if ((task == NULL || task == iev->task) && !iev->canceled) { if ((task == NULL || task == iev->task) && !iev->canceled) {
if (iev->posted) { if (iev->posted) {
if (isc_task_purge(task, sock, if (isc_task_purge(current_task, sock,
ISC_SOCKEVENT_INTCONN) ISC_SOCKEVENT_INTCONN)
== 0) { == 0) {
iev->canceled = ISC_TRUE; iev->canceled = ISC_TRUE;