prefork.c revision 133a47776e6bc3f11f3beac454e643240b675ff7
842ae4bd224140319ae7feec1872b93dfd491143fielding/* Licensed to the Apache Software Foundation (ASF) under one or more
842ae4bd224140319ae7feec1872b93dfd491143fielding * contributor license agreements. See the NOTICE file distributed with
842ae4bd224140319ae7feec1872b93dfd491143fielding * this work for additional information regarding copyright ownership.
842ae4bd224140319ae7feec1872b93dfd491143fielding * The ASF licenses this file to You under the Apache License, Version 2.0
842ae4bd224140319ae7feec1872b93dfd491143fielding * (the "License"); you may not use this file except in compliance with
842ae4bd224140319ae7feec1872b93dfd491143fielding * the License. You may obtain a copy of the License at
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * Unless required by applicable law or agreed to in writing, software
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * distributed under the License is distributed on an "AS IS" BASIS,
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * See the License for the specific language governing permissions and
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * limitations under the License.
c5d006b2861d49c61bcf79316163e30611c6fd08trawick/* Limit on the total --- clients will be locked out if more servers than
c5d006b2861d49c61bcf79316163e30611c6fd08trawick * this are needed. It is intended solely to keep the server from crashing
c5d006b2861d49c61bcf79316163e30611c6fd08trawick * when things get out of hand.
20f1b1a67eef5ab0f3295608c89964a7dca4fdd1pquerna * We keep a hard maximum number of servers, for two reasons --- first off,
20f1b1a67eef5ab0f3295608c89964a7dca4fdd1pquerna * in case something goes seriously wrong, we want to stop the fork bomb
20f1b1a67eef5ab0f3295608c89964a7dca4fdd1pquerna * short of actually crashing the machine we're running on by filling some
20f1b1a67eef5ab0f3295608c89964a7dca4fdd1pquerna * kernel table. Secondly, it keeps the size of the scoreboard file small
20f1b1a67eef5ab0f3295608c89964a7dca4fdd1pquerna * enough that we can read the whole thing without worrying too much about
20f1b1a67eef5ab0f3295608c89964a7dca4fdd1pquerna * the overhead.
20f1b1a67eef5ab0f3295608c89964a7dca4fdd1pquerna/* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT. We want
20f1b1a67eef5ab0f3295608c89964a7dca4fdd1pquerna * some sort of compile-time limit to help catch typos.
20f1b1a67eef5ab0f3295608c89964a7dca4fdd1pquerna/* config globals */
2d2eda71267231c2526be701fe655db125852c1ffieldingstatic int server_limit = 0;
d2227b43aaee9a78350dc107bdc404859ad1f938rbb/* data retained by prefork across load/unload of the module
2d2eda71267231c2526be701fe655db125852c1ffielding * allocated on first call to pre-config hook; located on
45acd673a68181802b112e97e84fa3813ddd3ec1stoddard * subsequent calls to pre-config hook
d2227b43aaee9a78350dc107bdc404859ad1f938rbbtypedef struct prefork_retained_data {
2d2eda71267231c2526be701fe655db125852c1ffielding * The max child slot ever assigned, preserved across restarts. Necessary
2d2eda71267231c2526be701fe655db125852c1ffielding * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts. We
3d96ee83babeec32482c9082c9426340cee8c44dwrowe * use this value to optimize routines that have to scan the entire scoreboard.
2d2eda71267231c2526be701fe655db125852c1ffielding * idle_spawn_rate is the number of children that will be spawned on the
2d2eda71267231c2526be701fe655db125852c1ffielding * next maintenance cycle if there aren't enough idle servers. It is
2d2eda71267231c2526be701fe655db125852c1ffielding * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
11e076839c8d5a82d55e710194d0daac51390dbdsf * without the need to spawn.
int idle_spawn_rate;
#ifndef MAX_SPAWN_RATE
static int one_process = 0;
static int my_child_num;
#ifdef GPROF
* configure in httpd.conf:
* GprofDir $RuntimeDir/ -> $ServerRoot/$RuntimeDir/gmon.out
* GprofDir $RuntimeDir/% -> $ServerRoot/$RuntimeDir/gprof.$pid/gmon.out
static void chdir_for_gprof(void)
const char *use_dir;
if(dir) {
#define chdir_for_gprof()
if (pchild) {
static void accept_mutex_on(void)
clean_child_exit(0);
static void accept_mutex_off(void)
switch(query_code){
case AP_MPMQ_MAX_DAEMON_USED:
case AP_MPMQ_IS_THREADED:
case AP_MPMQ_IS_FORKED:
case AP_MPMQ_MAX_THREADS:
*result = 0;
*result = 0;
case AP_MPMQ_MAX_DAEMONS:
case AP_MPMQ_MPM_STATE:
case AP_MPMQ_GENERATION:
return OK;
static const char *prefork_get_name(void)
clean_child_exit(0);
static int volatile shutdown_pending;
static int volatile restart_pending;
static int volatile die_now = 0;
static void set_signals(void)
#ifndef NO_USE_SIGACTION
if (!one_process) {
#ifndef NO_USE_SIGACTION
#ifdef AP_SIG_GRACEFUL_STOP
#ifdef SIGINT
#ifdef SIGXCPU
#ifdef SIGXFSZ
#ifdef SIGPIPE
ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(" AP_SIG_GRACEFUL_STRING ")");
if (!one_process) {
#ifdef SIGXCPU
#ifdef SIGXFSZ
#ifdef SIGHUP
#ifdef AP_SIG_GRACEFUL
#ifdef AP_SIG_GRACEFUL_STOP
#ifdef SIGPIPE
static int requests_this_child;
static int num_listensocks = 0;
#if APR_HAS_THREADS
int last_poll_idx = 0;
const char *lockfile;
requests_this_child = 0;
#if APR_HAS_THREADS
pchild);
void *csd;
if ((ap_max_requests_per_child > 0
clean_child_exit(0);
clean_child_exit(0);
last_poll_idx = 0;
goto got_fd;
current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, my_child_num, sbh, bucket_alloc);
if (current_conn) {
#if APR_HAS_THREADS
clean_child_exit(0);
int pid;
if (one_process) {
#ifdef SIGQUIT
#ifdef _OSD_POSIX
if (!pid) {
#ifdef HAVE_BINDPROCESSOR
int idle_count;
int free_length;
int last_non_dead;
int total_non_dead;
free_length = 0;
idle_count = 0;
total_non_dead = 0;
for (i = 0; i < ap_daemons_limit; ++i) {
int status;
++free_length;
++ idle_count;
last_non_dead = i;
if (free_length == 0) {
"to increase StartServers, or Min/MaxSpareServers), "
for (i = 0; i < free_length; ++i) {
int index;
s, _pconf, 0);
return DONE;
return DONE;
set_signals();
if (one_process) {
int child_slot;
return DONE;
if (child_slot >= 0) {
else if (remaining_children_to_start
0, ap_server_conf,
else if (remaining_children_to_start) {
return DONE;
} else if (shutdown_pending) {
int active_children;
active_children = 0;
if (ap_graceful_shutdown_timeout) {
shutdown_pending = 0;
active_children = 0;
return DONE;
if (one_process) {
return DONE;
return OK;
int startup = 0;
int level_flags = 0;
pconf = p;
return DONE;
return DONE;
return OK;
if (debug) {
no_detach = 0;
if (!retained) {
return HTTP_INTERNAL_SERVER_ERROR;
ap_extended_status = 0;
return OK;
int startup = 0;
if (startup) {
if (startup) {
if (startup) {
if (startup) {
if (ap_daemons_to_start < 0) {
if (startup) {
if (startup) {
return OK;
return err;
return NULL;
return err;
return NULL;
return err;
return NULL;
return err;
return NULL;
return err;
return NULL;
{ NULL }