diff options
author | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-07-30 18:37:07 -0400 |
---|---|---|
committer | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-07-30 18:37:07 -0400 |
commit | 3a2d76abecff6e8537e41f20273742ec13e30c1d (patch) | |
tree | 4e57f2b966555338d9b108c0bd2e1f86be2d1f19 /src | |
parent | 0566e2e2fbbeb82d383bf3e39c5a7014df315de0 (diff) | |
download | slapi-nis-3a2d76abecff6e8537e41f20273742ec13e30c1d.tar.gz slapi-nis-3a2d76abecff6e8537e41f20273742ec13e30c1d.tar.xz slapi-nis-3a2d76abecff6e8537e41f20273742ec13e30c1d.zip |
- remove a race when the main slapd thread closes down our listeners before
we get back from the poll(), by checking the pipe first and breaking out
immediately if we were told to shut down
Diffstat (limited to 'src')
-rw-r--r-- | src/disp-nis.c | 39 |
1 files changed, 20 insertions, 19 deletions
diff --git a/src/disp-nis.c b/src/disp-nis.c index 2baba69..71401b2 100644 --- a/src/disp-nis.c +++ b/src/disp-nis.c @@ -864,13 +864,12 @@ dispatch_thread(struct wrapped_thread *t) struct plugin_state *state = wrap_thread_arg(t); struct pollfd *fds; int i, n_fds, client_count; - bool_t stop; clients = NULL; client_count = 0; fds = NULL; - for (stop = FALSE; !stop;) { + while (state->n_listeners > 0) { /* Prune out recently-disconnected clients. */ list = &clients; while (*list != NULL) { @@ -922,17 +921,17 @@ dispatch_thread(struct wrapped_thread *t) memset(fds, 0, sizeof((state->n_listeners + client_count + 1) * sizeof(fds[0]))); - for (i = 0; i < state->n_listeners; i++) { - fds[i].fd = state->listener[i].fd; - fds[i].events = POLLIN; - } /* Add the shutdown pipe reader. */ - fds[i].fd = wrap_thread_stopfd(t); - fds[i].events = POLLIN; - if (fds[i].fd != -1) { - i++; + fds[0].fd = wrap_thread_stopfd(t); + fds[0].events = POLLIN; + + /* Add the listeners. */ + for (i = 0; i < state->n_listeners; i++) { + fds[i + 1].fd = state->listener[i].fd; + fds[i + 1].events = POLLIN; } + i++; /* Add the client list. */ client = clients; @@ -979,20 +978,27 @@ dispatch_thread(struct wrapped_thread *t) /* Save the head of the existing clients list. */ client = clients; + /* Check the shutdown pipe reader. */ + if (fds[0].revents & POLLIN) { + break; + } + /* Iterate over listening sockets which have work for us. */ for (i = 0; i < state->n_listeners; i++) { - if ((fds[i].revents & POLLIN) == 0) { + if ((fds[i + 1].revents & POLLIN) == 0) { continue; } switch (state->listener[i].type) { case SOCK_DGRAM: /* Datagram requests we handle right * here, right now. */ - dispatch_dgram(state, fds[i].fd); + dispatch_dgram(state, fds[i + 1].fd); break; case SOCK_STREAM: - /* Try to accept a new client. */ - next = dispatch_accept_client(state, fds[i].fd); + /* Try to accept a new client. New clients get + * inserted at the head of the list. */ + next = dispatch_accept_client(state, + fds[i + 1].fd); if (next != NULL) { slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, @@ -1008,11 +1014,6 @@ dispatch_thread(struct wrapped_thread *t) break; } } - - /* Add the shutdown pipe reader. */ - if (fds[i].revents & POLLIN) { - stop = TRUE; - } i++; /* Service the already-connected clients. */ |