]> granicus.if.org Git - apache/commitdiff
Win32: Add ThreadLimit directive to the windows MPM
authorBill Stoddard <stoddard@apache.org>
Wed, 28 Aug 2002 17:25:56 +0000 (17:25 +0000)
committerBill Stoddard <stoddard@apache.org>
Wed, 28 Aug 2002 17:25:56 +0000 (17:25 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@96555 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
server/mpm/winnt/mpm.h
server/mpm/winnt/mpm_winnt.c

diff --git a/CHANGES b/CHANGES
index 4d7863577cbff8cb38939ee27098de2a00ef4096..ed84035d161aac7a052a50953534beb3f863c419 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,6 @@
 Changes with Apache 2.0.41
+  *) Implement ThreadLimit directive in the Windows MPM.
+     [Bill Stoddard]
 
   *) Remove CacheOn config directive since it is set but never checked.
      No sense wasting cycles on unused code. Besides, the only truly
index 752af27a852d9a493965a16eda0b686eecba3498..c83c4b62f0edf20524b9873026c650b362d08d8a 100644 (file)
@@ -74,6 +74,7 @@
 #define AP_MPM_WANT_SET_SCOREBOARD
 
 extern int ap_threads_per_child;
+extern int ap_thread_limit;
 extern server_rec *ap_server_conf;
 
 #endif /* APACHE_MPM_H */
index 9e3e4e3b9a2f0db50cb3949f946c3f137d532a3a..df94fe2606b732a8386907caad22c558ba5fcd15 100644 (file)
 #include "apr_atomic.h"
 
 /* Limit on the threads per process.  Clients will be locked out if more than
- * this  * HARD_SERVER_LIMIT are needed.
+ * this  * server_limit are needed.
  *
  * We keep this for one reason it keeps the size of the scoreboard file small
  * enough that we can read the whole thing without worrying too much about
  * the overhead.
  */
-#ifndef HARD_THREAD_LIMIT
-#define HARD_THREAD_LIMIT 1920
+#ifndef DEFAULT_THREAD_LIMIT
+#define DEFAULT_THREAD_LIMIT 1920
+#endif
+
+/* Admin can't tune ThreadLimit beyond MAX_THREAD_LIMIT.  We want
+ * some sort of compile-time limit to help catch typos.
+ */
+#ifndef MAX_THREAD_LIMIT
+#define MAX_THREAD_LIMIT 15000
 #endif
 
 /* Limit on the total --- clients will be locked out if more servers than
@@ -126,6 +133,9 @@ static DWORD parent_pid;
 DWORD my_pid;
 
 int ap_threads_per_child = 0;
+static int thread_limit = DEFAULT_THREAD_LIMIT;
+static int first_thread_limit = 0;
+static int changed_limit_at_restart;
 
 /* ap_my_generation are used by the scoreboard code */
 ap_generation_t volatile ap_my_generation=0;
@@ -179,16 +189,17 @@ static const char *set_threads_per_child (cmd_parms *cmd, void *dummy, char *arg
     }
 
     ap_threads_per_child = atoi(arg);
-    if (ap_threads_per_child > HARD_THREAD_LIMIT) {
+    if (ap_threads_per_child > thread_limit) {
         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
-                     "WARNING: ThreadsPerChild of %d exceeds compile time"
-                     " limit of %d threads,", ap_threads_per_child, 
-                     HARD_THREAD_LIMIT);
+                     "WARNING: ThreadsPerChild of %d exceeds ThreadLimit "
+                     "value of %d threads,", ap_threads_per_child, 
+                     thread_limit);
         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
                      " lowering ThreadsPerChild to %d. To increase, please"
-                     " see the  HARD_THREAD_LIMIT define in %s.", 
-                     HARD_THREAD_LIMIT, AP_MPM_HARD_LIMITS_FILE);
-        ap_threads_per_child = HARD_THREAD_LIMIT;
+                     " see the", thread_limit);
+        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
+                     " ThreadLimit directive.");
+        ap_threads_per_child = thread_limit;
     }
     else if (ap_threads_per_child < 1) {
        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
@@ -197,11 +208,52 @@ static const char *set_threads_per_child (cmd_parms *cmd, void *dummy, char *arg
     }
     return NULL;
 }
+static const char *set_thread_limit (cmd_parms *cmd, void *dummy, const char *arg) 
+{
+    int tmp_thread_limit;
+    
+    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+    if (err != NULL) {
+        return err;
+    }
+
+    tmp_thread_limit = atoi(arg);
+    /* you cannot change ThreadLimit across a restart; ignore
+     * any such attempts
+     */
+    if (first_thread_limit &&
+        tmp_thread_limit != thread_limit) {
+        /* how do we log a message?  the error log is a bit bucket at this
+         * point; we'll just have to set a flag so that ap_mpm_run()
+         * logs a warning later
+         */
+        changed_limit_at_restart = 1;
+        return NULL;
+    }
+    thread_limit = tmp_thread_limit;
+    
+    if (thread_limit > MAX_THREAD_LIMIT) {
+       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
+                    "WARNING: ThreadLimit of %d exceeds compile time limit "
+                    "of %d threads,", thread_limit, MAX_THREAD_LIMIT);
+       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
+                    " lowering ThreadLimit to %d.", MAX_THREAD_LIMIT);
+       thread_limit = MAX_THREAD_LIMIT;
+    } 
+    else if (thread_limit < 1) {
+       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
+                     "WARNING: Require ThreadLimit > 0, setting to 1");
+       thread_limit = 1;
+    }
+    return NULL;
+}
 
 static const command_rec winnt_cmds[] = {
 LISTEN_COMMANDS,
-{ "ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF, TAKE1,
-  "Number of threads each child creates" },
+AP_INIT_TAKE1("ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF,
+  "Number of threads each child creates" ),
+AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF,
+  "Maximum worker threads in a server for this run of Apache"),
 { NULL }
 };
 
@@ -1030,7 +1082,7 @@ AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
             *result = HARD_SERVER_LIMIT;
             return APR_SUCCESS;
         case AP_MPMQ_HARD_LIMIT_THREADS:
-            *result = HARD_THREAD_LIMIT;
+            *result = thread_limit;
             return APR_SUCCESS;
         case AP_MPMQ_MAX_THREADS:
             *result = ap_threads_per_child;
@@ -1568,6 +1620,17 @@ AP_DECLARE(int) ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s )
 {
     static int restart = 0;            /* Default is "not a restart" */
 
+    if (!restart) {
+        first_thread_limit = thread_limit;
+    }
+
+    if (changed_limit_at_restart) {
+        ap_log_error(APLOG_MARK, APLOG_WARNING, APR_SUCCESS, ap_server_conf,
+                     "WARNING: Attempt to change ThreadLimit ignored "
+                     "during restart");
+        changed_limit_at_restart = 0;
+    }
+    
     /* ### If non-graceful restarts are ever introduced - we need to rerun 
      * the pre_mpm hook on subsequent non-graceful restarts.  But Win32 
      * has only graceful style restarts - and we need this hook to act