]> granicus.if.org Git - apache/commitdiff
restart fixes for worker:
authorJeff Trawick <trawick@apache.org>
Sun, 24 Feb 2002 20:53:26 +0000 (20:53 +0000)
committerJeff Trawick <trawick@apache.org>
Sun, 24 Feb 2002 20:53:26 +0000 (20:53 +0000)
fix a segfault and a window in which we could miss joining
newly-created threads

we can't try to signal workers if the worker queue hasn't
been initialized (or we segfault)

make sure the start thread is done creating threads before
we try to join; otherwise we can just miss some of them and
not be able to clean them up properly

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@93561 13f79535-47bb-0310-9956-ffa450edef68

server/mpm/worker/worker.c

index 61a63ae43612a873828baae6ac72850c0ddb674f..baa8ed159ae7f96d4532c4342d7f01c62095c8a3 100644 (file)
@@ -885,10 +885,39 @@ static void * APR_THREAD_FUNC start_threads(apr_thread_t *thd, void *dummy)
     return NULL;
 }
 
+static void join_workers(apr_thread_t **threads)
+{
+    int i;
+    apr_status_t rv, thread_rv;
+
+    for (i = 0; i < ap_threads_per_child; i++) {
+        if (threads[i]) { /* if we ever created this thread */
+            rv = apr_thread_join(&thread_rv, threads[i]);
+            if (rv != APR_SUCCESS) {
+                ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
+                             "apr_thread_join: unable to join worker "
+                             "thread %d",
+                             i);
+            }
+        }
+    }
+}
+
+static void join_start_thread(apr_thread_t *start_thread_id)
+{
+    apr_status_t rv, thread_rv;
+
+    rv = apr_thread_join(&thread_rv, start_thread_id);
+    if (rv != APR_SUCCESS) {
+        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
+                     "apr_thread_join: unable to join the start "
+                     "thread");
+    }
+}
+
 static void child_main(int child_num_arg)
 {
     apr_thread_t **threads;
-    int i;
     apr_status_t rv;
     thread_starter *ts;
     apr_threadattr_t *thread_attr;
@@ -961,7 +990,6 @@ static void child_main(int child_num_arg)
     ts->child_num_arg = child_num_arg;
     ts->threadattr = thread_attr;
 
-    
     rv = apr_thread_create(&start_thread_id, thread_attr, start_threads,
                            ts, pchild);
     if (rv != APR_SUCCESS) {
@@ -979,6 +1007,10 @@ static void child_main(int child_num_arg)
     if (one_process) {
         /* Set up a signal handler for this thread. */
         apr_signal_thread(check_signal);
+        /* make sure the start thread has finished; signal_workers() 
+         * and join_workers() depend on that
+         */
+        join_start_thread(start_thread_id);
         signal_workers(); /* helps us terminate a little more quickly when
                            * the dispatch of the signal thread
                            * beats the Pipe of Death and the browsers
@@ -990,18 +1022,17 @@ static void child_main(int child_num_arg)
          *   If the worker hasn't exited, then this blocks until
          *   they have (then cleans up).
          */
-        apr_thread_join(&rv, start_thread_id);
-        for (i = 0; i < ap_threads_per_child; i++) {
-            if (threads[i]) { /* if we ever created this thread */
-                apr_thread_join(&rv, threads[i]);
-            }
-        }
+        join_workers(threads);
     }
     else { /* !one_process */
         /* Watch for any messages from the parent over the POD */
         while (1) {
             rv = ap_mpm_pod_check(pod);
             if (rv == AP_GRACEFUL || rv == AP_RESTART) {
+                /* make sure the start thread has finished; 
+                 * signal_workers() and join_workers depend on that
+                 */
+                join_start_thread(start_thread_id);
                 signal_workers();
                 break;
             }
@@ -1015,12 +1046,7 @@ static void child_main(int child_num_arg)
              *   If the worker hasn't exited, then this blocks until
              *   they have (then cleans up).
              */
-            apr_thread_join(&rv, start_thread_id);
-            for (i = 0; i < ap_threads_per_child; i++) {
-                if (threads[i]) { /* if we ever created this thread */
-                    apr_thread_join(&rv, threads[i]);
-                }
-            }
+            join_workers(threads);
         }
     }