From: Ryan Bloom Date: Tue, 16 Oct 2001 04:02:28 +0000 (+0000) Subject: Port the MaxClients changes from the worker MPM to the threaded X-Git-Tag: 2.0.26~2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4d4ce3209a67277f381acfd1c1909b8bbae5dcc7;p=apache Port the MaxClients changes from the worker MPM to the threaded MPM. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@91483 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 23210ab1e7..57272811e5 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,8 @@ Changes with Apache 2.0.26-dev + *) Port the MaxClients changes from the worker MPM to the threaded + MPM. [Ryan Bloom] + *) Fix mod_proxy so that it handles chunked transfer-encoding and works with the new input filtering system. [Justin Erenkrantz] diff --git a/docs/conf/httpd-std.conf b/docs/conf/httpd-std.conf index 30cedd66c0..5e7d47a418 100644 --- a/docs/conf/httpd-std.conf +++ b/docs/conf/httpd-std.conf @@ -126,8 +126,8 @@ MaxRequestsPerChild 0 # MaxRequestsPerChild: maximum number of requests a server process serves StartServers 3 -MaxClients 8 -MinSpareThreads 5 +MaxClients 150 +MinSpareThreads 25 MaxSpareThreads 75 ThreadsPerChild 25 MaxRequestsPerChild 0 diff --git a/server/mpm/threaded/threaded.c b/server/mpm/threaded/threaded.c index 5a14e1ce78..8b4f583421 100644 --- a/server/mpm/threaded/threaded.c +++ b/server/mpm/threaded/threaded.c @@ -1359,6 +1359,44 @@ static void threaded_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t { static int restart_num = 0; int no_detach, debug; + ap_directive_t *pdir; + ap_directive_t *max_clients = NULL; + + /* make sure that "ThreadsPerChild" gets set before "MaxClients" */ + for (pdir = ap_conftree; pdir != NULL; pdir = pdir->next) { + if (strncasecmp(pdir->directive, "ThreadsPerChild", 15) == 0) { + if (!max_clients) { + break; /* we're in the clear, got ThreadsPerChild first */ + } + else { + /* now to swap the data */ + ap_directive_t temp; + + temp.directive = pdir->directive; + temp.args = pdir->args; + /* Make sure you don't change 'next', or you may get loops! */ + /* XXX: first_child, parent, and data can never be set + * for these directives, right? -aaron */ + temp.filename = pdir->filename; + temp.line_num = pdir->line_num; + + pdir->directive = max_clients->directive; + pdir->args = max_clients->args; + pdir->filename = max_clients->filename; + pdir->line_num = max_clients->line_num; + + max_clients->directive = temp.directive; + max_clients->args = temp.args; + max_clients->filename = temp.filename; + max_clients->line_num = temp.line_num; + break; + } + } + else if (!max_clients + && strncasecmp(pdir->directive, "MaxClients", 10) == 0) { + max_clients = pdir; + } + } debug = ap_exists_config_define("DEBUG"); @@ -1452,27 +1490,58 @@ static const char *set_max_spare_threads(cmd_parms *cmd, void *dummy, static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg) { + int max_clients; const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); if (err != NULL) { return err; } - - ap_daemons_limit = atoi(arg); + + /* It is ok to use ap_threads_per_child here because we are + * sure that it gets set before MaxClients in the pre_config stage. */ + max_clients = atoi(arg); + if (max_clients < ap_threads_per_child) { + ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, + "WARNING: MaxClients (%d) must be at least as large", + max_clients); + ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, + " large as ThreadsPerChild (%d). Automatically", + ap_threads_per_child); + ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, + " increasing MaxClients to %d.", + ap_threads_per_child); + max_clients = ap_threads_per_child; + } + ap_daemons_limit = max_clients / ap_threads_per_child; + if ((max_clients > 0) && (max_clients % ap_threads_per_child)) { + ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, + "WARNING: MaxClients (%d) is not an integer multiple", + max_clients); + ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, + " of ThreadsPerChild (%d), lowering MaxClients to %d", + ap_threads_per_child, + ap_daemons_limit * ap_threads_per_child); + ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, + " for a maximum of %d child processes,", + ap_daemons_limit); + } if (ap_daemons_limit > HARD_SERVER_LIMIT) { - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "WARNING: MaxClients of %d exceeds compile time limit " - "of %d servers,", ap_daemons_limit, HARD_SERVER_LIMIT); - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - " lowering MaxClients to %d. To increase, please " - "see the", HARD_SERVER_LIMIT); - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - " HARD_SERVER_LIMIT define in %s.", + ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, + "WARNING: MaxClients of %d would require %d servers,", + max_clients, ap_daemons_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, + " and would exceed the compile time limit of %d.", + HARD_SERVER_LIMIT); + ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, + " Automatically lowering MaxClients to %d. To increase,", + HARD_SERVER_LIMIT); + ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, + " please see the HARD_SERVER_LIMIT define in %s.", AP_MPM_HARD_LIMITS_FILE); ap_daemons_limit = HARD_SERVER_LIMIT; - } + } else if (ap_daemons_limit < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "WARNING: Require MaxClients > 0, setting to 1"); - ap_daemons_limit = 1; + ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "WARNING: Require MaxClients > 0, setting to 1"); + ap_daemons_limit = 1; } return NULL; }