Took a bit of digging but I found out when pthread_join was removed. I think removing
pthread join was a mistake, whatever the reason (reason not clear from the commit
comment). Perhaps the answer is in fdqueue.c...
The change was made by Manoj on the apache-apr tree on May 24, 1999.
1.16 / (download) - annotate - [select for diffs] , Mon May 24 06:18:47 1999 UTC (22
months, 3 weeks ago) by manoj
Bring queued model up-to-date with poll-accept model, for some reason.
This makes the accept threads use poll() on a pipe to discover that it's
time for a child process to die.
Also, since stop_accepting_requests() isn't used anymore (and doesn't
really work anyway), get rid of all references to it in both models.
===================================================================
RCS file: /home/cvs/apache-apr/pthreads/src/main/http_accept.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- apache-apr/pthreads/src/main/http_accept.c 1999/05/24 02:10:26 1.15
+++ apache-apr/pthreads/src/main/http_accept.c 1999/05/24 06:18:47 1.16
@@ -92,8 +92,11 @@
int my_tid = ti->tid;
int sd = ti->sd;
int csd = 0;
+ int srv, ret;
struct sockaddr sa_client;
size_t len = sizeof(struct sockaddr);
+ struct pollfd listenfds[2];
+ char pipe_read_char;
free(ti);
@@ -105,8 +108,17 @@
sock_disable_nagle(sd);
*/
+ listenfds[0].fd = ap_pipe_of_death[0];
+ listenfds[0].events = POLLIN;
+ listenfds[0].revents = 0;
+ listenfds[1].fd = sd;
+ listenfds[1].events = POLLIN;
+ listenfds[1].revents = 0;
+
while ((ap_max_requests_per_child != 0 && requests_this_child > 0) ||
(ap_max_requests_per_child == 0))
+ if (workers_may_exit)
+ break;
(void) ap_update_child_status(my_pid, my_tid, SERVER_ACCEPTING,
(request_rec *) NULL);
/* lock around the accept if necessary */
@@ -123,10 +135,33 @@
csd = -1;
}
else {
- csd = accept(sd, &sa_client, &len);
- requests_this_child--;
- SAFE_ACCEPT(accept_mutex_off(my_tid - ap_threads_per_child));
- SAFE_ACCEPT(intra_mutex_off(my_tid - ap_threads_per_child));
+ for (;;) {
+ srv = poll(listenfds, 2, -1);
+ if (listenfds[0].revents & POLLIN) {
+ /* A process has gotten a signal on the shutdown pipe.
+ * Check if we're the lucky process to die. */
+ ret = read(listenfds[0].fd, &pipe_read_char, 1);
+ if (ret == -1 && errno == EAGAIN) {
+ /* It lost the lottery. It must continue to suffer
+ * through a life of servitude */
+ continue;
+ }
+ else {
+ /* It won the lottery (or something else is very
+ * wrong). Embrace death with open arms. */
+ workers_may_exit = 1;
+ pthread_cond_broadcast(&(csd_queue.not_empty));
+ csd = -1;
+ break;
+ }
+ } else {
+ csd = accept(sd, &sa_client, &len);
+ requests_this_child--;
+ break;
+ }
+ }
+ SAFE_ACCEPT(accept_mutex_off(my_tid - ap_threads_per_child));
+ SAFE_ACCEPT(intra_mutex_off(my_tid - ap_threads_per_child));
}
(void) ap_update_child_status(my_pid, my_tid, SERVER_QUEUEING,
(request_rec *) NULL);
@@ -139,66 +174,10 @@
}
}
- /* Raise SIGWINCH so that all the actions that go with a gradual,
- * graceful shutdown of the process get done.
- *
- * The reason this thread is actually going through the trouble to
- * look up its own process ID is because under Red Hat 5.2, getpid()
- * actually returns the "process ID" of the thread, since threads
- * are just processes that share everything. I hope this is fixed in
- * glibc 2.1 & Linux 2.2. - mvsk */
- kill(ap_scoreboard_image->parent[my_pid].pid, SIGWINCH);
ap_update_child_status(my_pid, my_tid, SERVER_DEAD, (request_rec *) NULL);
return NULL;
}
-
-/* Kill off any worker threads by kicking them out of whatever they are doing
- * and allowing them to see that requests_this_child == 0.
- * It is possible this function could be defined to be NULL in some accept
- * models.
- */
-
-static void kill_workers(void)
-{
- int i;
- int index = find_child_by_pid(getpid());
- parent_score *ss = &ap_scoreboard_image->parent[index];
-
- pthread_cond_broadcast(&(csd_queue.not_empty));
- for (i = 0; i < ss->worker_threads; i++) {
- pthread_join(ap_scoreboard_image->servers[index][i].tid, NULL);
- }
-}
-/* Kill off any acceptor threads by kicking them out of what they are doing
- * and allowing them to see that requests_this_child == 0.
- * It is possible this function could be defined to be NULL in some accept
- * models.
- */
-static void kill_acceptors(pool* pconf)
-{
- listen_rec *lr;
- int i;
- int index = find_child_by_pid(getpid());
- parent_score *ss = &ap_scoreboard_image->parent[index];
-
-
- /* Kick acceptor threads out of accept */
-
- lr = ap_listeners;
- while (lr != NULL) {
- ap_pclosesocket(pconf, lr->fd);
- lr= lr->next;
- }
-
- /* Kick any acceptor out of blocking on a full queue */
- pthread_cond_broadcast(&(csd_queue.not_full));
-
- for (i = ss->worker_threads; i < ss->worker_threads + ss->acceptor_threads; i++) {
- pthread_join(ap_scoreboard_image->servers[index][i].tid, NULL);
- }
-}
-
void accept_parent_init(pool *pconf, int listener_count)
{
SAFE_ACCEPT(accept_mutex_init(pconf, listener_count));
@@ -308,14 +287,6 @@
return csd;
}
-void stop_accepting_connections(pool* pconf)
-{
- requests_this_child = 0;
- /* The two functions to get all of our other threads to die off. */
- kill_acceptors(pconf);
- workers_may_exit = 1;
- kill_workers();
-}
#elif defined(USE_MULTI_ACCEPT)
@@ -481,22 +452,6 @@
}
workers_may_exit = 1;
return -1;
-}
-
-void stop_accepting_connections(pool* pconf)
-{
- int i;
- int index = find_child_by_pid(getpid());
-
- parent_score *ss = &ap_scoreboard_image->parent[index];
-
- requests_this_child = 0;
- workers_may_exit = 1;
-
- for (i = 0; i < ss->worker_threads; i++) {
- pthread_join(ap_scoreboard_image->servers[index][i].tid, NULL);
- }
-
}
#endif
> On Fri, 13 Apr 2001, Bill Stoddard wrote:
>
> > I have not reviewed Paul's patch but he and I have discussed it and I am +1 on
concept.
> > Having the main thread join the workers at shutdown ensures that the main thread
>will
not
> > exit before all the workers have exited. Not unlike what I am doing in the windows
mpm
> > with waitformultipleobject.
> >
> > Our policy is commit the review.
>
> Yes, but this approach was taken a long time ago, and I am uncomfortable
> going back to it until we know why it was removed back then.
>
> Ryan
>
>
>
> _______________________________________________________________________________
> Ryan Bloom [EMAIL PROTECTED]
> 406 29th St.
> San Francisco, CA 94131
> -------------------------------------------------------------------------------
>