httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From grega...@apache.org
Subject svn commit: r168182 - in /httpd/httpd/trunk: CHANGES server/mpm/experimental/event/event.c server/mpm/worker/worker.c
Date Wed, 04 May 2005 20:00:23 GMT
Author: gregames
Date: Wed May  4 13:00:23 2005
New Revision: 168182

URL: http://svn.apache.org/viewcvs?rev=168182&view=rev
Log:
worker and event mpms: transient thread creation errors shouldn't take down
the whole server.

Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/server/mpm/experimental/event/event.c
    httpd/httpd/trunk/server/mpm/worker/worker.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/CHANGES?rev=168182&r1=168181&r2=168182&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES (original)
+++ httpd/httpd/trunk/CHANGES Wed May  4 13:00:23 2005
@@ -2,6 +2,9 @@
 
   [Remove entries to the current 2.0 section below, when backported]
 
+  *) worker and event mpms: don't take down the whole server for a transient
+     thread creation failure.  PR 34514 [Greg Ames]
+
   *) ap_get_local_host() rewritten for APR. [Jim Jagielski]
 
   *) Add the ap_vhost_iterate_given_conn function to expose the information

Modified: httpd/httpd/trunk/server/mpm/experimental/event/event.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/server/mpm/experimental/event/event.c?rev=168182&r1=168181&r2=168182&view=diff
==============================================================================
--- httpd/httpd/trunk/server/mpm/experimental/event/event.c (original)
+++ httpd/httpd/trunk/server/mpm/experimental/event/event.c Wed May  4 13:00:23 2005
@@ -160,6 +160,7 @@
 static fd_queue_t *worker_queue;
 static fd_queue_info_t *worker_queue_info;
 static int mpm_state = AP_MPMQ_STARTING;
+static int sick_child_detected;
 
 apr_thread_mutex_t *timeout_mutex;
 APR_RING_HEAD(timeout_head_t, conn_state_t);
@@ -1166,14 +1167,8 @@
     if (rv != APR_SUCCESS) {
         ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
                      "apr_thread_create: unable to create listener thread");
-        /* In case system resources are maxxed out, we don't want
-         * Apache running away with the CPU trying to fork over and
-         * over and over again if we exit.
-         * XXX Jeff doesn't see how Apache is going to try to fork again since
-         * the exit code is APEXIT_CHILDFATAL
-         */
-        apr_sleep(apr_time_from_sec(10));
-        clean_child_exit(APEXIT_CHILDFATAL);
+        /* let the parent decide how bad this really is */
+        clean_child_exit(APEXIT_CHILDSICK);
     }
     apr_os_thread_get(&listener_os_thread, ts->listener);
 }
@@ -1251,11 +1246,8 @@
             if (rv != APR_SUCCESS) {
                 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
                              "apr_thread_create: unable to create worker thread");
-                /* In case system resources are maxxed out, we don't want
-                   Apache running away with the CPU trying to fork over and
-                   over and over again if we exit. */
-                apr_sleep(apr_time_from_sec(10));
-                clean_child_exit(APEXIT_CHILDFATAL);
+                /* let the parent decide how bad this really is */
+                clean_child_exit(APEXIT_CHILDSICK);
             }
             threads_created++;
         }
@@ -1627,6 +1619,7 @@
     int free_slots[MAX_SPAWN_RATE];
     int last_non_dead;
     int total_non_dead;
+    int active_thread_count = 0;
 
     /* initialize the free_list */
     free_length = 0;
@@ -1664,13 +1657,15 @@
              * So we hopefully won't need to fork more if we count it.
              * This depends on the ordering of SERVER_READY and SERVER_STARTING.
              */
-            if (status <= SERVER_READY && status != SERVER_DEAD &&
-                !ps->quiescing && ps->generation == ap_my_generation &&
-                /* XXX the following shouldn't be necessary if we clean up 
-                 *     properly after seg faults, but we're not yet    GLA 
-                 */
-                ps->pid != 0) {
-                ++idle_thread_count;
+            if (ps->pid != 0) { /* XXX just set all_dead_threads in outer
+                                   for loop if no pid?  not much else matters */
+                if (status <= SERVER_READY && status != SERVER_DEAD &&
+                        !ps->quiescing && ps->generation == ap_my_generation)
{
+                    ++idle_thread_count;
+                }
+                if (status >= SERVER_READY && status < SERVER_GRACEFUL) {
+                    ++active_thread_count;
+                }
             }
         }
         if (any_dead_threads 
@@ -1702,6 +1697,28 @@
             ++total_non_dead;
         }
     }
+
+    if (sick_child_detected) {
+        if (active_thread_count > 0) {
+            /* some child processes appear to be working.  don't kill the
+             * whole server.
+             */
+            sick_child_detected = 0;
+        }
+        else {
+            /* looks like a basket case.  give up.  
+             */
+            shutdown_pending = 1;
+            child_fatal = 1;
+            ap_log_error(APLOG_MARK, APLOG_ALERT, 0,
+                         ap_server_conf,
+                         "No active workers found..."
+                         " Apache is exiting!");
+            /* the child already logged the failure details */
+            return;
+        }
+    }
+                                                    
     ap_max_daemons_limit = last_non_dead + 1;
 
     if (idle_thread_count > max_spare_threads) {
@@ -1774,6 +1791,12 @@
                 shutdown_pending = 1;
                 child_fatal = 1;
                 return;
+            }
+            else if (processed_status == APEXIT_CHILDSICK) {
+                /* tell perform_idle_server_maintenance to check into this
+                 * on the next timer pop
+                 */
+                sick_child_detected = 1;
             }
             /* non-fatal death... note that it's gone in the scoreboard. */
             child_slot = find_child_by_pid(&pid);

Modified: httpd/httpd/trunk/server/mpm/worker/worker.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/server/mpm/worker/worker.c?rev=168182&r1=168181&r2=168182&view=diff
==============================================================================
--- httpd/httpd/trunk/server/mpm/worker/worker.c (original)
+++ httpd/httpd/trunk/server/mpm/worker/worker.c Wed May  4 13:00:23 2005
@@ -134,6 +134,7 @@
 static fd_queue_t *worker_queue;
 static fd_queue_info_t *worker_queue_info;
 static int mpm_state = AP_MPMQ_STARTING;
+static int sick_child_detected;
 
 /* The structure used to pass unique initialization info to each thread */
 typedef struct {
@@ -896,14 +897,8 @@
     if (rv != APR_SUCCESS) {
         ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
                      "apr_thread_create: unable to create listener thread");
-        /* In case system resources are maxxed out, we don't want
-         * Apache running away with the CPU trying to fork over and
-         * over and over again if we exit.
-         * XXX Jeff doesn't see how Apache is going to try to fork again since
-         * the exit code is APEXIT_CHILDFATAL
-         */
-        apr_sleep(apr_time_from_sec(10));
-        clean_child_exit(APEXIT_CHILDFATAL);
+        /* let the parent decide how bad this really is */
+        clean_child_exit(APEXIT_CHILDSICK);
     }
     apr_os_thread_get(&listener_os_thread, ts->listener);
 }
@@ -980,11 +975,8 @@
             if (rv != APR_SUCCESS) {
                 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
                     "apr_thread_create: unable to create worker thread");
-                /* In case system resources are maxxed out, we don't want
-                   Apache running away with the CPU trying to fork over and
-                   over and over again if we exit. */
-                apr_sleep(apr_time_from_sec(10));
-                clean_child_exit(APEXIT_CHILDFATAL);
+                /* let the parent decide how bad this really is */
+                clean_child_exit(APEXIT_CHILDSICK);
             }
             threads_created++;
         }
@@ -1373,6 +1365,7 @@
     int free_slots[MAX_SPAWN_RATE];
     int last_non_dead;
     int total_non_dead;
+    int active_thread_count = 0;
 
     /* initialize the free_list */
     free_length = 0;
@@ -1410,14 +1403,16 @@
              * So we hopefully won't need to fork more if we count it.
              * This depends on the ordering of SERVER_READY and SERVER_STARTING.
              */
-            if (status <= SERVER_READY && status != SERVER_DEAD &&
-                    !ps->quiescing &&
-                    ps->generation == ap_my_generation &&
-                 /* XXX the following shouldn't be necessary if we clean up 
-                  *     properly after seg faults, but we're not yet    GLA 
-                  */     
-                    ps->pid != 0) {
-                ++idle_thread_count;
+            if (ps->pid != 0) { /* XXX just set all_dead_threads in outer for
+                                   loop if no pid?  not much else matters */
+                if (status <= SERVER_READY && status != SERVER_DEAD &&
+                        !ps->quiescing &&
+                        ps->generation == ap_my_generation) {
+                    ++idle_thread_count;
+                }
+                if (status >= SERVER_READY && status < SERVER_GRACEFUL) {
+                    ++active_thread_count;
+                }
             }
         }
         if (any_dead_threads && totally_free_length < idle_spawn_rate
@@ -1448,6 +1443,28 @@
             ++total_non_dead;
         }
     }
+
+    if (sick_child_detected) {
+        if (active_thread_count > 0) {
+            /* some child processes appear to be working.  don't kill the
+             * whole server.
+             */
+            sick_child_detected = 0;
+        }
+        else {
+            /* looks like a basket case.  give up.  
+             */
+            shutdown_pending = 1;
+            child_fatal = 1;
+            ap_log_error(APLOG_MARK, APLOG_ALERT, 0,
+                         ap_server_conf,
+                         "No active workers found..."
+                         " Apache is exiting!");
+            /* the child already logged the failure details */
+            return;
+        }
+    }
+                                                    
     ap_max_daemons_limit = last_non_dead + 1;
 
     if (idle_thread_count > max_spare_threads) {
@@ -1520,6 +1537,12 @@
                 shutdown_pending = 1;
                 child_fatal = 1;
                 return;
+            }
+            else if (processed_status == APEXIT_CHILDSICK) {
+                /* tell perform_idle_server_maintenance to check into this
+                 * on the next timer pop
+                 */
+                sick_child_detected = 1;
             }
             /* non-fatal death... note that it's gone in the scoreboard. */
             child_slot = find_child_by_pid(&pid);



Mime
View raw message