prefork.c revision 5ad238c42b1e159ee8f164515e0c4ee6c727c2fd
4e67ddd6b39c2847cc399ab0874427baa7ea8935Lennart Poettering/* ====================================================================
4e67ddd6b39c2847cc399ab0874427baa7ea8935Lennart Poettering * The Apache Software License, Version 1.1
4e67ddd6b39c2847cc399ab0874427baa7ea8935Lennart Poettering * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
4e67ddd6b39c2847cc399ab0874427baa7ea8935Lennart Poettering * Redistribution and use in source and binary forms, with or without
4e67ddd6b39c2847cc399ab0874427baa7ea8935Lennart Poettering * modification, are permitted provided that the following conditions
4e67ddd6b39c2847cc399ab0874427baa7ea8935Lennart Poettering * 1. Redistributions of source code must retain the above copyright
4e67ddd6b39c2847cc399ab0874427baa7ea8935Lennart Poettering * notice, this list of conditions and the following disclaimer.
* Apache Software Foundation (http://www.apache.org/)."
#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>
#define CORE_PRIVATE
#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"
#ifdef HAVE_BSTRING_H
#ifdef HAVE_TIME_H
#include <time.h>
#ifdef HAVE_SYS_PROCESSOR_H
#include <signal.h>
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 one_process = 0;
#ifndef MULTITHREAD
static int my_child_num;
#ifdef TPF
int tpf_child = 0;
static int die_now = 0;
#ifdef GPROF
* configure in httpd.conf:
* GprofDir logs/ -> $ServerRoot/logs/gmon.out
* GprofDir logs/% -> $ServerRoot/logs/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) {
if (rv) {
if (rv) {
static void accept_mutex_on(void)
static void accept_mutex_off(void)
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;
return APR_ENOTIMPL;
#if defined(NEED_WAITPID)
int n, pid;
for (n = 0; n < ap_max_daemons_limit; ++n) {
*exitcode = 0;
return(pid);
0, ap_server_conf,
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) {
#if defined(SA_ONESHOT)
#ifdef SIGBUS
#ifdef SIGABORT
#ifdef SIGABRT
#ifdef SIGILL
#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 SIGBUS
#ifdef SIGABORT
#ifdef SIGABRT
#ifdef SIGILL
#ifdef SIGXCPU
#ifdef SIGXFSZ
#ifdef SIGHUP
#ifdef AP_SIG_GRACEFUL
#ifdef SIGPIPE
static int requests_this_child;
static int num_listensocks = 0;
int ap_graceful_stop_signalled(void)
int offset;
void *csd;
requests_this_child = 0;
if (unixd_setup_child()) {
(void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(my_child_num), SERVER_READY, (request_rec *) NULL);
for (i = 0; i < num_listensocks; i++)
while (!die_now) {
if ((ap_max_requests_per_child > 0
clean_child_exit(0);
(void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(my_child_num), SERVER_READY, (request_rec *) NULL);
apr_int32_t n;
offset = 0;
goto got_fd;
curr_pollfd++;
curr_pollfd = 0;
goto got_fd;
if (current_conn) {
clean_child_exit(0);
int pid;
if (one_process) {
#ifdef SIGQUIT
(void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(slot), SERVER_STARTING, (request_rec *) NULL);
#ifdef _OSD_POSIX
if (!pid) {
#ifdef HAVE_BINDPROCESSOR
#ifdef SCOREBOARD_FILE
sizeof(process_score));
#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;
ap_server_conf = s;
if (!is_graceful) {
#ifdef SCOREBOARD_FILE
set_signals();
if (!is_graceful) {
int child_slot;
int status;
if (child_slot >= 0) {
else if (is_graceful) {
0, ap_server_conf,
else if (remaining_children_to_start) {
#ifdef TPF
if (shutdown_pending) {
0, ap_server_conf,
if (one_process) {
if (is_graceful) {
#ifndef SCOREBOARD_FILE
static int restart_num = 0;
if (debug)
is_graceful = 0;
ap_extended_status = 0;
#ifdef AUX3
(void) set42sig();
return err;
return NULL;
return err;
if (ap_daemons_min_free <= 0) {
return NULL;
return err;
return NULL;
return err;
return NULL;
{ NULL }