prefork.c revision d0aad1cd29a348a32edf8783600ac8a09ba4329c
70e59ed31c5a9c9ed02d9065ddf92be87c887efbJakub Hrozek/* Licensed to the Apache Software Foundation (ASF) under one or more
70e59ed31c5a9c9ed02d9065ddf92be87c887efbJakub Hrozek * contributor license agreements. See the NOTICE file distributed with
70e59ed31c5a9c9ed02d9065ddf92be87c887efbJakub Hrozek * this work for additional information regarding copyright ownership.
70e59ed31c5a9c9ed02d9065ddf92be87c887efbJakub Hrozek * The ASF licenses this file to You under the Apache License, Version 2.0
70e59ed31c5a9c9ed02d9065ddf92be87c887efbJakub Hrozek * (the "License"); you may not use this file except in compliance with
70e59ed31c5a9c9ed02d9065ddf92be87c887efbJakub Hrozek * the License. You may obtain a copy of the License at
70e59ed31c5a9c9ed02d9065ddf92be87c887efbJakub Hrozek * Unless required by applicable law or agreed to in writing, software
70e59ed31c5a9c9ed02d9065ddf92be87c887efbJakub Hrozek * distributed under the License is distributed on an "AS IS" BASIS,
70e59ed31c5a9c9ed02d9065ddf92be87c887efbJakub Hrozek * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
70e59ed31c5a9c9ed02d9065ddf92be87c887efbJakub Hrozek * See the License for the specific language governing permissions and
70e59ed31c5a9c9ed02d9065ddf92be87c887efbJakub Hrozek * limitations under the License.
#include "apr.h"
#include "apr_portable.h"
#include "apr_strings.h"
#include "apr_thread_proc.h"
#include "apr_signal.h"
#define APR_WANT_STDIO
#define APR_WANT_STRFUNC
#include "apr_want.h"
#include <unistd.h>
#include "ap_config.h"
#include "httpd.h"
#include "mpm_default.h"
#include "http_main.h"
#include "http_log.h"
#include "http_config.h"
#include "http_connection.h"
#include "scoreboard.h"
#include "ap_mpm.h"
#include "unixd.h"
#include "mpm_common.h"
#include "ap_listen.h"
#include "ap_mmn.h"
#include "apr_poll.h"
#ifdef HAVE_BSTRING_H
#ifdef HAVE_TIME_H
#include <time.h>
#ifdef HAVE_SYS_PROCESSOR_H
#include <signal.h>
#ifndef DEFAULT_SERVER_LIMIT
#ifndef MAX_SERVER_LIMIT
#ifndef HARD_THREAD_LIMIT
static int ap_daemons_to_start=0;
static int ap_daemons_min_free=0;
static int ap_daemons_max_free=0;
static int server_limit = 0;
static int first_server_limit = 0;
static int one_process = 0;
#ifndef MULTITHREAD
static int my_child_num;
#ifdef TPF
int tpf_child = 0;
static volatile int die_now = 0;
#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()
#define ap_check_signals()
if (pchild) {
static void accept_mutex_on(void)
if (ap_my_generation !=
clean_child_exit(0);
static void accept_mutex_off(void)
if (ap_my_generation !=
switch(query_code){
case AP_MPMQ_MAX_DAEMON_USED:
return APR_SUCCESS;
case AP_MPMQ_IS_THREADED:
return APR_SUCCESS;
case AP_MPMQ_IS_FORKED:
return APR_SUCCESS;
return APR_SUCCESS;
return APR_SUCCESS;
case AP_MPMQ_MAX_THREADS:
*result = 0;
return APR_SUCCESS;
return APR_SUCCESS;
*result = 0;
return APR_SUCCESS;
return APR_SUCCESS;
*result = 0;
return APR_SUCCESS;
return APR_SUCCESS;
case AP_MPMQ_MAX_DAEMONS:
return APR_SUCCESS;
case AP_MPMQ_MPM_STATE:
return APR_SUCCESS;
return APR_ENOTIMPL;
clean_child_exit(0);
static int volatile shutdown_pending;
static int volatile restart_pending;
static int volatile is_graceful;
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;
int last_poll_idx = 0;
requests_this_child = 0;
void *csd;
if ((ap_max_requests_per_child > 0
clean_child_exit(0);
else if (die_now) {
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) {
else if (ap_my_generation !=
clean_child_exit(0);
int pid;
if (one_process) {
#ifdef SIGQUIT
#ifdef _OSD_POSIX
if (!pid) {
#ifdef HAVE_BINDPROCESSOR
#ifndef MAX_SPAWN_RATE
static int hold_off_on_exponential_spawning;
int to_kill;
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;
to_kill = i;
last_non_dead = i;
if (free_length == 0) {
static int reported = 0;
if (!reported) {
"to increase StartServers, or Min/MaxSpareServers), "
for (i = 0; i < free_length; ++i) {
#ifdef TPF
int index;
if (!is_graceful) {
set_signals();
if (one_process) {
if (!is_graceful) {
int child_slot;
if (child_slot >= 0) {
else if (remaining_children_to_start
else if (is_graceful) {
0, ap_server_conf,
else if (remaining_children_to_start) {
#ifdef TPF
0, ap_server_conf,
} else if (shutdown_pending) {
int active_children;
active_children = 0;
0, ap_server_conf,
if (ap_graceful_shutdown_timeout) {
shutdown_pending = 0;
active_children = 0;
if (one_process) {
if (is_graceful) {
static int restart_num = 0;
int startup = 0;
int level_flags = 0;
pconf = p;
ap_server_conf = s;
if (restart_num++ == 0) {
return DONE;
return DONE;
return OK;
static int restart_num = 0;
if (debug) {
no_detach = 0;
is_graceful = 0;
return HTTP_INTERNAL_SERVER_ERROR;
ap_extended_status = 0;
#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE
return OK;
static int restart_num = 0;
int startup = 0;
if (restart_num++ == 0) {
if (startup) {
if (startup) {
if (!first_server_limit) {
if (startup) {
if (startup) {
if (ap_daemons_to_start < 0) {
if (startup) {
if (startup) {
return OK;
#ifdef AUX3
(void) set42sig();
return err;
return NULL;
return err;
return NULL;
return err;
return NULL;
return err;
return NULL;
return err;
return NULL;
{ NULL }