manoj 99/04/15 13:01:43
Modified: pthreads/src/main http_main.c http_accept.c Log: Enable graceful restart and MaxRequestsPerChild for the multiaccept model, using a pipe watched by poll() to wake up the server at the child's graceful shutdown time. Revision Changes Path 1.72 +1 -0 apache-apr/pthreads/src/main/http_main.c Index: http_main.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/http_main.c,v retrieving revision 1.71 retrieving revision 1.72 diff -u -u -r1.71 -r1.72 --- http_main.c 1999/04/14 22:44:57 1.71 +++ http_main.c 1999/04/15 20:01:40 1.72 @@ -1762,6 +1762,7 @@ } ap_destroy_pool(ptrans); + kill(ap_scoreboard_image->parent[process_slot].pid, SIGWINCH); ap_update_child_status(process_slot, thread_slot, SERVER_DEAD, (request_rec *) NULL); return NULL; 1.7 +29 -24 apache-apr/pthreads/src/main/http_accept.c Index: http_accept.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/http_accept.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -u -r1.6 -r1.7 --- http_accept.c 1999/04/14 22:44:57 1.6 +++ http_accept.c 1999/04/15 20:01:40 1.7 @@ -317,6 +317,7 @@ */ static listen_rec *head_listener; static struct pollfd *listenfds; +static int pipe_of_death; void accept_parent_init(pool *pconf, int listener_count) { @@ -329,15 +330,26 @@ int worker_threads_per_child) { int i; + int pipe_pair_of_death[2]; listen_rec *lr; SAFE_ACCEPT(accept_mutex_child_init(pchild)); requests_this_child = ap_max_requests_per_child; head_listener = ap_listeners; - listenfds = ap_palloc(pchild, sizeof(struct pollfd) * num_listenfds); + listenfds = ap_palloc(pchild, sizeof(struct pollfd) * (num_listenfds + 1)); - for (lr = ap_listeners, i = 0; i < num_listenfds; lr = lr->next, ++i) { + if (pipe(pipe_pair_of_death) == -1) { + ap_log_error(APLOG_MARK, APLOG_ERR, + (const server_rec*) ap_get_server_conf(), + "pipe: (pipe_of_death)"); + clean_child_exit(1); + } + pipe_of_death = pipe_pair_of_death[0]; + listenfds[0].fd = pipe_pair_of_death[1]; + listenfds[0].events = POLLIN; + listenfds[0].revents = 0; + for (lr = ap_listeners, i = 1; i <= num_listenfds; lr = lr->next, ++i) { lr->index = i; listenfds[i].fd = lr->fd; listenfds[i].events = POLLIN; /* should we add POLLPRI ?*/ @@ -368,12 +380,19 @@ if (workers_may_exit) break; - if (num_listenfds > 1) { + /* XXX - Yes, we always go through the poll, at least for now. + * - mvsk + */ + if (1) { /* more than one socket */ - srv = poll(listenfds, num_listenfds, -1); + srv = poll(listenfds, num_listenfds + 1, -1); if (workers_may_exit) break; if (srv < 0) { + /* XXX - hmmmm, poll can return EINTR. - mvsk */ + if (errno == EINTR) { + continue; + } SAFE_ACCEPT(accept_mutex_off(0)); /* Single Unix documents select as returning errnos * EBADF, EINTR, and EINVAL... and in none of those @@ -427,6 +446,7 @@ } csd = accept(sd, sa_client, &len); + requests_this_child--; if (csd >= 0) break; /* We have a socket ready for reading */ @@ -442,39 +462,24 @@ break; } } - - /* If the workers have not already been signaled to die, SIGWINCH the parent to - * kick-off the restart - */ - if (!workers_may_exit) { - index = find_child_by_pid(getpid()); - kill(ap_scoreboard_image->parent[index].pid, SIGWINCH); - } - - return -1; - } + void stop_accepting_connections(pool* pconf) { - - listen_rec *lr; int i; int index = find_child_by_pid(getpid()); + char char_of_death = '!'; parent_score *ss = &ap_scoreboard_image->parent[index]; requests_this_child = 0; workers_may_exit = 1; - /* Kick threads out of poll/accept */ - lr = ap_listeners; - while (lr != NULL) { - ap_pclosesocket(pconf, lr->fd); - lr= lr->next; - } + /* Kick threads out of poll */ + (void) write(pipe_of_death, &char_of_death, 1); - for (i = 0; i < ss->worker_threads + ss->acceptor_threads; i++) { + for (i = 0; i < ss->worker_threads; i++) { pthread_join(ap_scoreboard_image->servers[index][i].tid, NULL); }