]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
mpm_event: Follow up to r1895553.
authorYann Ylavic <ylavic@apache.org>
Mon, 6 Dec 2021 17:12:28 +0000 (17:12 +0000)
committerYann Ylavic <ylavic@apache.org>
Mon, 6 Dec 2021 17:12:28 +0000 (17:12 +0000)
We can still kill processes above MaxSpareThreads at every maintenance cycle
unless there is not enough headromm in the scoreboard for a graceful restart.

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

server/mpm/event/event.c

index 1d6d78f61084c94fd0d384c138cb226a18854391..8e5bc8e0febd6837fcca5145a3cf543779f4022f 100644 (file)
@@ -3187,7 +3187,8 @@ static void perform_idle_server_maintenance(int child_bucket)
          * gracefully finishing processes may accumulate, filling up the
          * scoreboard. To avoid running out of scoreboard entries, we
          * don't shut down more processes if there are stopping ones
-         * already (i.e. active_daemons < total_daemons).
+         * already (i.e. active_daemons != total_daemons) and not enough
+         * slack space in the scoreboard for a graceful restart.
          *
          * XXX It would be nice if we could
          * XXX - kill processes without keepalive connections first
@@ -3195,20 +3196,25 @@ static void perform_idle_server_maintenance(int child_bucket)
          * XXX   depending on server load, later be able to resurrect them
          *       or kill them
          */
-        int ignore = (retained->active_daemons < retained->total_daemons);
+        int do_kill = (retained->active_daemons == retained->total_daemons
+                       || (server_limit - retained->total_daemons >
+                           active_daemons_limit));
         ap_log_error(APLOG_MARK, APLOG_TRACE5, 0, ap_server_conf,
                      "%shutting down one child: "
                      "active daemons %d / active limit %d / "
                      "total daemons %d / ServerLimit %d / "
                      "idle threads %d / max workers %d",
-                     (ignore) ? "Not s" : "S",
+                     (do_kill) ? "S" : "Not s",
                      retained->active_daemons, active_daemons_limit,
                      retained->total_daemons, server_limit,
                      idle_thread_count, max_workers);
-        if (!ignore) {
+        if (do_kill) {
             ap_mpm_podx_signal(retained->buckets[child_bucket].pod,
                                AP_MPM_PODX_GRACEFUL);
         }
+        else {
+            /* Wait for dying daemon(s) to exit */
+        }
         retained->idle_spawn_rate[child_bucket] = 1;
     }
     else if (idle_thread_count < min_spare_threads / num_buckets) {