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
> -------------------------------------------------------------------------------
>

Reply via email to