mpm_netware.c revision b89b35cce5ae706ee1ec75425799edf7f694f7fb
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering/* ====================================================================
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering * The Apache Software License, Version 1.1
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering * Copyright (c) 2000-2003 The Apache Software Foundation. All rights
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering * Redistribution and use in source and binary forms, with or without
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering * modification, are permitted provided that the following conditions
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering * 1. Redistributions of source code must retain the above copyright
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering * notice, this list of conditions and the following disclaimer.
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering * 2. Redistributions in binary form must reproduce the above copyright
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering * notice, this list of conditions and the following disclaimer in
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering * the documentation and/or other materials provided with the
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering * distribution.
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering * 3. The end-user documentation included with the redistribution,
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering * if any, must include the following acknowledgment:
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering * "This product includes software developed by the
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering * Apache Software Foundation (http://www.apache.org/)."
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering * Alternately, this acknowledgment may appear in the software itself,
56ba3c78ae35065064c4289a0c8e22a81256af20Zbigniew Jędrzejewski-Szmek * if and wherever such third-party acknowledgments normally appear.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * 4. The names "Apache" and "Apache Software Foundation" must
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * not be used to endorse or promote products derived from this
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * software without prior written permission. For written
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * permission, please contact apache@apache.org.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * 5. Products derived from this software may not be called "Apache",
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * nor may "Apache" appear in their name, without prior written
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * permission of the Apache Software Foundation.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * ====================================================================
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * This software consists of voluntary contributions made by many
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * individuals on behalf of the Apache Software Foundation. For more
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * information on the Apache Software Foundation, please see
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * Portions of this software are based upon public domain software
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * originally written at the National Center for Supercomputing Applications,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * University of Illinois, Urbana-Champaign.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * httpd.c: simple http daemon for answering WWW file requests
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * 03-21-93 Rob McCool wrote original code (up to NCSA HTTPd 1.3)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * 03-06-95 blong
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * changed server number for child-alone processes to 0 and changed name
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * 03-10-95 blong
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * Added numerous speed hacks proposed by Robert S. Thau (rst@ai.mit.edu)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * including set group before fork, and call gettime before to fork
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * to set up libraries.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * 04-14-95 rst / rh
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * Brandon's code snarfed from NCSA 1.4, but tinkered to work with the
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * Apache server, and also to have child processes do accept() directly.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * April-July '95 rst
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * Extensive rework for Apache.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "http_core.h" /* for get_remote_host */
707b66c66381c899d7ef640e158ffdd5bcff4debLennart Poettering/* Limit on the total --- clients will be locked out if more servers than
707b66c66381c899d7ef640e158ffdd5bcff4debLennart Poettering * this are needed. It is intended solely to keep the server from crashing
707b66c66381c899d7ef640e158ffdd5bcff4debLennart Poettering * when things get out of hand.
707b66c66381c899d7ef640e158ffdd5bcff4debLennart Poettering * We keep a hard maximum number of servers, for two reasons --- first off,
707b66c66381c899d7ef640e158ffdd5bcff4debLennart Poettering * in case something goes seriously wrong, we want to stop the fork bomb
707b66c66381c899d7ef640e158ffdd5bcff4debLennart Poettering * short of actually crashing the machine we're running on by filling some
707b66c66381c899d7ef640e158ffdd5bcff4debLennart Poettering * kernel table. Secondly, it keeps the size of the scoreboard file small
707b66c66381c899d7ef640e158ffdd5bcff4debLennart Poettering * enough that we can read the whole thing without worrying too much about
707b66c66381c899d7ef640e158ffdd5bcff4debLennart Poettering * the overhead.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#define WORKER_STARTING SERVER_STARTING
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#define WORKER_READY SERVER_READY
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#define WORKER_IDLE_KILL SERVER_IDLE_KILL
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/* config globals */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekint ap_threads_per_child=0; /* Worker threads per child */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int ap_threads_to_start=0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int ap_threads_min_free=0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int ap_threads_max_free=0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * The max child slot ever assigned, preserved across restarts. Necessary
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * to deal with MaxClients changes across SIGWINCH restarts. We use this
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * value to optimize routines that have to scan the entire scoreboard.
static int listenmaxfd;
static int die_now = 0;
static unsigned long worker_thread_count;
static int request_count;
/* Structure used to register/deregister a console handler with the OS */
static int InstallConsoleHandler(void);
static void RemoveConsoleHandler(void);
#define HANDLEDCOMMAND 0
static int show_settings = 0;
#ifdef DBPRINT_ON
#define DBPRINT0(s)
static int volatile shutdown_pending;
static int volatile restart_pending;
static int volatile is_graceful;
static void clean_child_exit(int code, int worker_num, apr_pool_t *ptrans, apr_bucket_alloc_t *bucket_alloc) __attribute__ ((noreturn));
static void clean_child_exit(int code, int worker_num, apr_pool_t *ptrans, apr_bucket_alloc_t *bucket_alloc)
if (!shutdown_pending) {
if (worker_num >=0)
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:
return APR_SUCCESS;
*result = 0;
return APR_SUCCESS;
return APR_SUCCESS;
*result = 0;
return APR_SUCCESS;
return APR_SUCCESS;
return APR_SUCCESS;
case AP_MPMQ_MAX_DAEMONS:
return APR_SUCCESS;
return APR_ENOTIMPL;
static void mpm_term(void)
wait_to_finish = 0;
while (wait_to_finish) {
static void restart(void)
static void set_signals(void)
if (wait) {
while (wait_to_finish) {
int ap_graceful_stop_signalled(void)
#ifdef DBINFO_ON
static int would_block = 0;
static int retry_success = 0;
static int retry_fail = 0;
static int avg_retries = 0;
int requests_this_child = 0;
int sockdes;
int srv;
int wouldblock_retry;
while (!die_now) {
if ((ap_max_requests_per_child > 0
if (shutdown_pending || restart_pending || (ap_scoreboard_image->servers[0][my_worker_num].status == WORKER_IDLE_KILL)) {
if (srv <= 0) {
if (srv < 0) {
if (!lr)
goto got_listener;
if (!lr)
while (wouldblock_retry) {
if (wouldblock_retry--) {
#ifdef DBINFO_ON
#ifdef DBINFO_ON
would_block++;
retry_fail++;
if (current_conn) {
int tid;
int err=0;
if (ctx = NXContextAlloc((void (*)(void *)) worker_main, (void*)slot, NX_PRIO_MED, ap_thread_stack_size, NX_CTX_NORMAL, &err)) {
if (err) {
if (err) {
#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_threads_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) {
static void display_settings ()
#ifdef DBINFO_ON
would_block = 0;
request_count = 0;
for (i=0;i<SERVER_NUM_STATUS;i++) {
status_array[i] = 0;
for (i = 0; i < ap_threads_limit; ++i) {
for (i=0;i<SERVER_NUM_STATUS;i++) {
case SERVER_DEAD:
case SERVER_STARTING:
case SERVER_READY:
case SERVER_BUSY_READ:
case SERVER_BUSY_WRITE:
case SERVER_BUSY_KEEPALIVE:
case SERVER_BUSY_LOG:
case SERVER_BUSY_DNS:
case SERVER_CLOSING:
case SERVER_GRACEFUL:
case SERVER_IDLE_KILL:
if (i != SERVER_DEAD)
#ifdef DBINFO_ON
static void show_server_data()
module **m;
int sockdes;
static int shutdown_listeners()
ap_server_conf = s;
if (setup_listeners(s)) {
worker_thread_count = 0;
if (!is_graceful) {
set_signals();
request_count = 0;
if (hold_screen_on_exit > 0) {
hold_screen_on_exit = 0;
if (show_settings)
while (worker_thread_count > 0)
while (worker_thread_count > 0) {
int debug;
is_graceful = 0;
if (addrname) {
ap_extended_status = 0;
return OK;
char *def_server_root;
const char *opt_arg;
for (i=len; i; i--) {
s[i] = NULL;
if (opt_arg) {
if (opt_arg) {
char *pID;
return NOTMYCOMMAND;
return NOTMYCOMMAND;
return NOTMYCOMMAND;
if (pID) {
pID++;
return NOTMYCOMMAND;
restart();
if (show_settings) {
show_settings = 0;
show_settings = 0;
return HANDLEDCOMMAND;
return NOTMYCOMMAND;
static int InstallConsoleHandler(void)
static void RemoveConsoleHandler(void)
return err;
return NULL;
return err;
if (ap_threads_min_free <= 0) {
return NULL;
return err;
return NULL;
return err;
return NULL;
const char *arg)
return err;
return NULL;
{ NULL }