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);
}