summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-07-30 18:37:07 -0400
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-07-30 18:37:07 -0400
commit3a2d76abecff6e8537e41f20273742ec13e30c1d (patch)
tree4e57f2b966555338d9b108c0bd2e1f86be2d1f19 /src
parent0566e2e2fbbeb82d383bf3e39c5a7014df315de0 (diff)
downloadslapi-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.c39
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. */