httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From traw...@apache.org
Subject cvs commit: httpd-2.0/server/mpm/prefork prefork.c
Date Wed, 19 Dec 2001 14:49:23 GMT
trawick     01/12/19 06:49:23

  Modified:    .        CHANGES
               server/mpm/worker worker.c
               server/mpm/prefork prefork.c
  Log:
  Add directives to worker and preform MPMs so that the admin can set
  the equivalent of HARD_SERVER_LIMIT/HARD_THREAD_LIMIT at startup.
  
  Revision  Changes    Path
  1.480     +3 -1      httpd-2.0/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/CHANGES,v
  retrieving revision 1.479
  retrieving revision 1.480
  diff -u -r1.479 -r1.480
  --- CHANGES	2001/12/18 21:56:15	1.479
  +++ CHANGES	2001/12/19 14:49:22	1.480
  @@ -1,9 +1,11 @@
   Changes with Apache 2.0.30-dev
  +
     *) Win32: Fix bug that could cause CGI scripts with QUERY_STRINGS
        to fail. [Bill Stoddard]
   
     *) Change core code to allow an MPM to set hard thread/server
  -     limits at startup.  [Jeff Trawick]
  +     limits at startup.  prefork and worker MPMs now have directives
  +     to set these limits.  [Jeff Trawick]
   
     *) Win32: The async AcceptEx() event should be autoreset upon
        successful completion of a wait (WaitForSingleObject). This
  
  
  
  1.50      +138 -29   httpd-2.0/server/mpm/worker/worker.c
  
  Index: worker.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/server/mpm/worker/worker.c,v
  retrieving revision 1.49
  retrieving revision 1.50
  diff -u -r1.49 -r1.50
  --- worker.c	2001/12/18 21:33:27	1.49
  +++ worker.c	2001/12/19 14:49:22	1.50
  @@ -122,19 +122,33 @@
    * enough that we can read the whole thing without worrying too much about
    * the overhead.
    */
  -#ifndef HARD_SERVER_LIMIT
  -#define HARD_SERVER_LIMIT 16
  +#ifndef DEFAULT_SERVER_LIMIT
  +#define DEFAULT_SERVER_LIMIT 16
   #endif
   
  +/* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT.  We want
  + * some sort of compile-time limit to help catch typos.
  + */
  +#ifndef MAX_SERVER_LIMIT
  +#define MAX_SERVER_LIMIT 20000
  +#endif
  +
   /* 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 DEFAULT_THREAD_LIMIT
  +#define DEFAULT_THREAD_LIMIT 64 
  +#endif
  +
  +/* Admin can't tune ThreadLimit beyond MAX_THREAD_LIMIT.  We want
  + * some sort of compile-time limit to help catch typos.
    */
  -#ifndef HARD_THREAD_LIMIT
  -#define HARD_THREAD_LIMIT 64 
  +#ifndef MAX_THREAD_LIMIT
  +#define MAX_THREAD_LIMIT 20000
   #endif
   
   /*
  @@ -145,7 +159,12 @@
   static int ap_daemons_to_start = 0;
   static int min_spare_threads = 0;
   static int max_spare_threads = 0;
  -static int ap_daemons_limit = 0;
  +static int ap_daemons_limit = 0;      /* MaxClients */
  +static int server_limit = DEFAULT_SERVER_LIMIT;
  +static int first_server_limit;
  +static int thread_limit = DEFAULT_THREAD_LIMIT;
  +static int first_thread_limit;
  +static int changed_limit_at_restart;
   static int dying = 0;
   static int workers_may_exit = 0;
   static int requests_this_child;
  @@ -168,7 +187,7 @@
       apr_threadattr_t *threadattr;
   } thread_starter;
   
  -#define ID_FROM_CHILD_THREAD(c, t)    ((c * HARD_THREAD_LIMIT) + t)
  +#define ID_FROM_CHILD_THREAD(c, t)    ((c * thread_limit) + t)
   
   /*
    * The max child slot ever assigned, preserved across restarts.  Necessary
  @@ -249,10 +268,10 @@
               *result = AP_MPMQ_DYNAMIC;
               return APR_SUCCESS;
           case AP_MPMQ_HARD_LIMIT_DAEMONS:
  -            *result = HARD_SERVER_LIMIT;
  +            *result = 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;
  @@ -1348,7 +1367,15 @@
   
       pconf = _pconf;
       ap_server_conf = s;
  -
  +    first_server_limit = server_limit;
  +    first_thread_limit = thread_limit;
  +    if (changed_limit_at_restart) {
  +        ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, 0, s,
  +                     "WARNING: Attempt to change ServerLimit or ThreadLimit "
  +                     "ignored during restart");
  +        changed_limit_at_restart = 0;
  +    }
  +    
       if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) {
           /* XXX: hey, what's the right way for the mpm to indicate a fatal error? */
           ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ALERT, 0, s,
  @@ -1570,7 +1597,7 @@
       ap_daemons_to_start = DEFAULT_START_DAEMON;
       min_spare_threads = DEFAULT_MIN_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
       max_spare_threads = DEFAULT_MAX_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
  -    ap_daemons_limit = HARD_SERVER_LIMIT;
  +    ap_daemons_limit = server_limit;
       ap_threads_per_child = DEFAULT_THREADS_PER_CHILD;
       ap_pid_fname = DEFAULT_PIDLOG;
       ap_scoreboard_fname = DEFAULT_SCOREBOARD;
  @@ -1634,7 +1661,7 @@
       return NULL;
   }
   
  -static const char *set_server_limit (cmd_parms *cmd, void *dummy,
  +static const char *set_max_clients (cmd_parms *cmd, void *dummy,
                                        const char *arg) 
   {
       int max_clients;
  @@ -1672,20 +1699,19 @@
                       ap_daemons_limit);
          max_clients = ap_daemons_limit * ap_threads_per_child; 
       }
  -    if (ap_daemons_limit > HARD_SERVER_LIMIT) {
  +    if (ap_daemons_limit > server_limit) {
          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);
  +                    " and would exceed the ServerLimit value of %d.",
  +                    server_limit);
          ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
                       " Automatically lowering MaxClients to %d.  To increase,",
  -                    HARD_SERVER_LIMIT);
  +                    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;
  +                    " please see the ServerLimit directive.");
  +       ap_daemons_limit = server_limit;
       } 
       else if (ap_daemons_limit < 1) {
           ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
  @@ -1704,18 +1730,17 @@
       }
   
       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 | APLOG_NOERRNO, 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", ap_threads_per_child,
  +                     thread_limit);
           ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
  -                     " lowering ThreadsPerChild to %d. To increase, please"
  -                     " see the", HARD_THREAD_LIMIT);
  +                     "threads, lowering ThreadsPerChild to %d. To increase, please"
  +                     " see the", thread_limit);
           ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
  -                     " HARD_THREAD_LIMIT define in %s.",
  -                     AP_MPM_HARD_LIMITS_FILE);
  -        ap_threads_per_child = HARD_THREAD_LIMIT;
  +                     " ThreadLimit directive.");
  +        ap_threads_per_child = thread_limit;
       }
       else if (ap_threads_per_child < 1) {
           ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
  @@ -1725,6 +1750,86 @@
       return NULL;
   }
   
  +static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg) 
  +{
  +    int tmp_server_limit;
  +    
  +    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
  +    if (err != NULL) {
  +        return err;
  +    }
  +
  +    tmp_server_limit = atoi(arg);
  +    /* you cannot change ServerLimit across a restart; ignore
  +     * any such attempts
  +     */
  +    if (first_server_limit &&
  +        tmp_server_limit != server_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;
  +    }
  +    server_limit = tmp_server_limit;
  +    
  +    if (server_limit > MAX_SERVER_LIMIT) {
  +       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
  +                    "WARNING: ServerLimit of %d exceeds compile time limit "
  +                    "of %d servers,", server_limit, MAX_SERVER_LIMIT);
  +       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
  +                    " lowering ServerLimit to %d.", MAX_SERVER_LIMIT);
  +       server_limit = MAX_SERVER_LIMIT;
  +    } 
  +    else if (server_limit < 1) {
  +	ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
  +                     "WARNING: Require ServerLimit > 0, setting to 1");
  +	server_limit = 1;
  +    }
  +    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 | APLOG_NOERRNO, 0, NULL, 
  +                    "WARNING: ThreadLimit of %d exceeds compile time limit "
  +                    "of %d servers,", thread_limit, MAX_THREAD_LIMIT);
  +       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 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 | APLOG_NOERRNO, 0, NULL, 
  +                     "WARNING: Require ThreadLimit > 0, setting to 1");
  +	thread_limit = 1;
  +    }
  +    return NULL;
  +}
  +
   static const command_rec worker_cmds[] = {
   UNIX_DAEMON_COMMANDS,
   LISTEN_COMMANDS,
  @@ -1734,10 +1839,14 @@
     "Minimum number of idle children, to handle request spikes"),
   AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF,
     "Maximum number of idle children"),
  -AP_INIT_TAKE1("MaxClients", set_server_limit, NULL, RSRC_CONF,
  +AP_INIT_TAKE1("MaxClients", set_max_clients, NULL, RSRC_CONF,
     "Maximum number of children alive at the same time"),
   AP_INIT_TAKE1("ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF,
     "Number of threads each child creates"),
  +AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF,
  +  "Maximum value of MaxClients for this run of Apache"),
  +AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF,
  +  "Maximum worker threads in a server for this run of Apache"),
   { NULL }
   };
   
  
  
  
  1.226     +73 -16    httpd-2.0/server/mpm/prefork/prefork.c
  
  Index: prefork.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/server/mpm/prefork/prefork.c,v
  retrieving revision 1.225
  retrieving revision 1.226
  diff -u -r1.225 -r1.226
  --- prefork.c	2001/12/18 13:48:53	1.225
  +++ prefork.c	2001/12/19 14:49:22	1.226
  @@ -114,10 +114,17 @@
    * enough that we can read the whole thing without worrying too much about
    * the overhead.
    */
  -#ifndef HARD_SERVER_LIMIT
  -#define HARD_SERVER_LIMIT 256
  +#ifndef DEFAULT_SERVER_LIMIT
  +#define DEFAULT_SERVER_LIMIT 256
   #endif
   
  +/* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT.  We want
  + * some sort of compile-time limit to help catch typos.
  + */
  +#ifndef MAX_SERVER_LIMIT
  +#define MAX_SERVER_LIMIT 20000
  +#endif
  +
   #ifndef HARD_THREAD_LIMIT
   #define HARD_THREAD_LIMIT 1
   #endif
  @@ -129,7 +136,10 @@
   static int ap_daemons_to_start=0;
   static int ap_daemons_min_free=0;
   static int ap_daemons_max_free=0;
  -static int ap_daemons_limit=0;
  +static int ap_daemons_limit=0;      /* MaxClients */
  +static int server_limit = DEFAULT_SERVER_LIMIT;
  +static int first_server_limit;
  +static int changed_limit_at_restart;
   
   static ap_pod_t *pod;
   
  @@ -319,7 +329,7 @@
               *result = AP_MPMQ_DYNAMIC;
               return APR_SUCCESS;
           case AP_MPMQ_HARD_LIMIT_DAEMONS:
  -            *result = HARD_SERVER_LIMIT;
  +            *result = server_limit;
               return APR_SUCCESS;
           case AP_MPMQ_HARD_LIMIT_THREADS:
               *result = HARD_THREAD_LIMIT;
  @@ -964,9 +974,15 @@
       apr_status_t rv;
   
       pconf = _pconf;
  -
       ap_server_conf = s;
  - 
  +    first_server_limit = server_limit;
  +    if (changed_limit_at_restart) {
  +        ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, 0, s,
  +                     "WARNING: Attempt to change ServerLimit "
  +                     "ignored during restart");
  +        changed_limit_at_restart = 0;
  +    }
  +
       if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) {
   	/* XXX: hey, what's the right way for the mpm to indicate a fatal error? */
           ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ALERT, 0, s,
  @@ -1212,7 +1228,7 @@
       ap_daemons_to_start = DEFAULT_START_DAEMON;
       ap_daemons_min_free = DEFAULT_MIN_FREE_DAEMON;
       ap_daemons_max_free = DEFAULT_MAX_FREE_DAEMON;
  -    ap_daemons_limit = HARD_SERVER_LIMIT;
  +    ap_daemons_limit = server_limit;
       ap_pid_fname = DEFAULT_PIDLOG;
       ap_scoreboard_fname = DEFAULT_SCOREBOARD;
       ap_lock_fname = DEFAULT_LOCKFILE;
  @@ -1274,7 +1290,7 @@
       return NULL;
   }
   
  -static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg) 
  +static const char *set_max_clients (cmd_parms *cmd, void *dummy, const char *arg) 
   {
       const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
       if (err != NULL) {
  @@ -1282,17 +1298,16 @@
       }
   
       ap_daemons_limit = atoi(arg);
  -    if (ap_daemons_limit > HARD_SERVER_LIMIT) {
  +    if (ap_daemons_limit > 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);
  +                    "WARNING: MaxClients of %d exceeds ServerLimit value "
  +                    "of %d servers,", ap_daemons_limit, 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);
  +                    "see the ServerLimit", server_limit);
          ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
  -                    " HARD_SERVER_LIMIT define in %s.",
  -                    AP_MPM_HARD_LIMITS_FILE);
  -       ap_daemons_limit = HARD_SERVER_LIMIT;
  +                    " directive.");
  +       ap_daemons_limit = server_limit;
       } 
       else if (ap_daemons_limit < 1) {
   	ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
  @@ -1302,6 +1317,46 @@
       return NULL;
   }
   
  +static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg) 
  +{
  +    int tmp_server_limit;
  +    
  +    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
  +    if (err != NULL) {
  +        return err;
  +    }
  +
  +    tmp_server_limit = atoi(arg);
  +    /* you cannot change ServerLimit across a restart; ignore
  +     * any such attempts
  +     */
  +    if (first_server_limit &&
  +        tmp_server_limit != server_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;
  +    }
  +    server_limit = tmp_server_limit;
  +    
  +    if (server_limit > MAX_SERVER_LIMIT) {
  +       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
  +                    "WARNING: ServerLimit of %d exceeds compile time limit "
  +                    "of %d servers,", server_limit, MAX_SERVER_LIMIT);
  +       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
  +                    " lowering ServerLimit to %d.", MAX_SERVER_LIMIT);
  +       server_limit = MAX_SERVER_LIMIT;
  +    } 
  +    else if (server_limit < 1) {
  +	ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
  +                     "WARNING: Require ServerLimit > 0, setting to 1");
  +	server_limit = 1;
  +    }
  +    return NULL;
  +}
  +
   static const command_rec prefork_cmds[] = {
   UNIX_DAEMON_COMMANDS,
   LISTEN_COMMANDS,
  @@ -1311,8 +1366,10 @@
                 "Minimum number of idle children, to handle request spikes"),
   AP_INIT_TAKE1("MaxSpareServers", set_max_free_servers, NULL, RSRC_CONF,
                 "Maximum number of idle children"),
  -AP_INIT_TAKE1("MaxClients", set_server_limit, NULL, RSRC_CONF,
  +AP_INIT_TAKE1("MaxClients", set_max_clients, NULL, RSRC_CONF,
                 "Maximum number of children alive at the same time"),
  +AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF,
  +              "Maximum value of MaxClients for this run of Apache"),
   { NULL }
   };
   
  
  
  

Mime
View raw message