mpmt_pthread.c revision d936d7dcfc1a35dec2a026d23053f8230301cdff
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance/* ====================================================================
e32f2729ffc4e828e41a528f47a4815d4a1689f0Felix Gabriel Mance * Copyright (c) 1995-1999 The Apache Group. All rights reserved.
e32f2729ffc4e828e41a528f47a4815d4a1689f0Felix Gabriel Mance * Redistribution and use in source and binary forms, with or without
e32f2729ffc4e828e41a528f47a4815d4a1689f0Felix Gabriel Mance * modification, are permitted provided that the following conditions
e32f2729ffc4e828e41a528f47a4815d4a1689f0Felix Gabriel Mance * 1. Redistributions of source code must retain the above copyright
e32f2729ffc4e828e41a528f47a4815d4a1689f0Felix Gabriel Mance * notice, this list of conditions and the following disclaimer.
e32f2729ffc4e828e41a528f47a4815d4a1689f0Felix Gabriel Mance * 2. Redistributions in binary form must reproduce the above copyright
e32f2729ffc4e828e41a528f47a4815d4a1689f0Felix Gabriel Mance * notice, this list of conditions and the following disclaimer in
e32f2729ffc4e828e41a528f47a4815d4a1689f0Felix Gabriel Mance * the documentation and/or other materials provided with the
e32f2729ffc4e828e41a528f47a4815d4a1689f0Felix Gabriel Mance * distribution.
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * 3. All advertising materials mentioning features or use of this
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * software must display the following acknowledgment:
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * "This product includes software developed by the Apache Group
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * for use in the Apache HTTP server project (http://www.apache.org/)."
fc05327b875b5723b6c17849b83477f29ec12c90Felix Gabriel Mance * 4. The names "Apache Server" and "Apache Group" must not be used to
fc05327b875b5723b6c17849b83477f29ec12c90Felix Gabriel Mance * endorse or promote products derived from this software without
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * prior written permission. For written permission, please contact
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * apache@apache.org.
fc05327b875b5723b6c17849b83477f29ec12c90Felix Gabriel Mance * 5. Products derived from this software may not be called "Apache"
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * nor may "Apache" appear in their names without prior written
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * permission of the Apache Group.
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * 6. Redistributions of any form whatsoever must retain the following
fc05327b875b5723b6c17849b83477f29ec12c90Felix Gabriel Mance * acknowledgment:
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * "This product includes software developed by the Apache Group
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * for use in the Apache HTTP server project (http://www.apache.org/)."
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1cc559ec103ed20967587fff2e39cc88669f7b8fFelix Gabriel Mance * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1cc559ec103ed20967587fff2e39cc88669f7b8fFelix Gabriel Mance * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * OF THE POSSIBILITY OF SUCH DAMAGE.
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * ====================================================================
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * This software consists of voluntary contributions made by many
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * individuals on behalf of the Apache Group and was originally based
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * on public domain software written at the National Center for
fc05327b875b5723b6c17849b83477f29ec12c90Felix Gabriel Mance * Supercomputing Applications, University of Illinois, Urbana-Champaign.
e05e1babc9a0edf2ebd39713d5c44fd0a035d6daFelix Gabriel Mance * For more information on the Apache Group and the Apache HTTP server
e05e1babc9a0edf2ebd39713d5c44fd0a035d6daFelix Gabriel Mance * project, please see <http://www.apache.org/>.
7c2291b25eadfb81c4850bf7ea92a3168f547fa9Felix Gabriel Mance#include "http_config.h" /* for read_config */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance#include "http_core.h" /* for get_remote_host */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * Actual definitions of config globals
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Manceint ap_threads_per_child=0; /* Worker threads per child */
6e7fe479953725884826bd38e4779229d45d3a40Felix Gabriel ManceAPI_VAR_EXPORT int ap_extended_status = 0;
6e7fe479953725884826bd38e4779229d45d3a40Felix Gabriel Mance/* The structure used to pass unique initialization info to each thread */
6e7fe479953725884826bd38e4779229d45d3a40Felix Gabriel Mancetypedef struct {
7c2291b25eadfb81c4850bf7ea92a3168f547fa9Felix Gabriel Mance ap_context_t *tpool; /* "pthread" would be confusing */
396f82c6cd926be759b60fd1e854acfde7068215Felix Gabriel Mance#define SAFE_ACCEPT(stmt) do {if (ap_listeners->next != NULL) {stmt;}} while (0)
static int one_process = 0;
#ifdef DEBUG_SIGSTOP
int raise_sigstop_flags;
#ifdef HAS_OTHER_CHILD
struct other_child_rec {
int pid;
void *data;
int write_fd;
static int worker_thread_count;
return (server_conf);
return max_daemons_limit;
if (pchild) {
#ifdef HAS_OTHER_CHILD
static void probe_writable_fds(void)
int fd_max;
int rc;
fd_max = 0;
if (fd_max == 0)
if (rc == 0)
int i, status;
int not_dead_yet;
#ifdef HAS_OTHER_CHILD
not_dead_yet = 0;
for (i = 0; i < max_daemons_limit; ++i) {
++not_dead_yet;
switch (tries) {
pid);
pid);
#ifdef HAS_OTHER_CHILD
else if (waitret == 0) {
++not_dead_yet;
if (!not_dead_yet) {
#ifndef INTERVAL_OF_WRITABLE_PROBES
static int wait_or_timeout_counter;
int ret;
#ifdef HAS_OTHER_CHILD
if (ret > 0) {
return ret;
clean_child_exit(0);
static int volatile shutdown_pending;
static int volatile restart_pending;
static int volatile is_graceful;
void ap_start_shutdown(void)
#ifndef WIN32
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
if (!one_process) {
#ifdef SIGBUS
#ifdef SIGABORT
#ifdef SIGABRT
#ifdef SIGILL
#ifdef SIGXCPU
#ifdef SIGXFSZ
#ifdef SIGHUP
#ifdef SIGWINCH
#ifdef SIGPIPE
pid);
case SIGTERM:
case SIGHUP:
case SIGUSR1:
case SIGKILL:
#ifdef SYS_SIGLIST
#ifdef WCOREDUMP
#ifdef WCOREDUMP
int num_listeners = 0;
return num_listeners;
int ap_graceful_stop_signalled(void)
return is_graceful;
static void process_socket(ap_context_t *p, struct sockaddr *sa_client, int csd, int my_child_num, int my_thread_num)
conn_id);
static void check_pipe_of_death(void)
if (!workers_may_exit) {
int ret;
char pipe_read_char;
int srv;
int thesock;
while (!workers_may_exit) {
if (workers_may_exit) break;
if (workers_may_exit) {
while (!workers_may_exit) {
if (srv < 0) {
if (workers_may_exit) break;
goto got_fd;
curr_pollfd++;
goto got_fd;
if (!workers_may_exit) {
if (worker_thread_count == 0) {
return NULL;
int signal_received;
if (unixd_setup_child()) {
worker_thread_count = 0;
for (i=0; i < ap_threads_per_child; i++) {
#ifndef NO_THREADS
switch (signal_received) {
case SIGTERM:
case SIGINT:
int pid;
if (one_process) {
set_signals();
if (!pid) {
#ifdef AIX_BIND_PROCESSOR
#ifndef MAX_SPAWN_RATE
static int hold_off_on_exponential_spawning;
static void perform_idle_server_maintenance(void)
int idle_thread_count;
int free_length;
int last_non_dead;
int total_non_dead;
free_length = 0;
idle_thread_count = 0;
total_non_dead = 0;
for (i = 0; i < ap_daemons_limit; ++i) {
int any_dying_threads = 0;
int idle_thread_addition = 0;
for (j = 0; j < ap_threads_per_child; j++) {
++free_length;
if (!all_dead_threads) {
last_non_dead = i;
if (!any_dying_threads) {
if (free_length == 0) {
static int reported = 0;
if (!reported) {
"or Min/MaxSparetThreads), "
for (i = 0; i < free_length; ++i) {
int child_slot;
int pid;
if (pid >= 0) {
if (child_slot >= 0) {
for (i = 0; i < ap_threads_per_child; i++)
#ifdef HAS_OTHER_CHILD
else if (is_graceful) {
else if (remaining_children_to_start) {
server_conf = s;
server_conf = s;
if (!is_graceful) {
set_signals();
if (!is_graceful) {
if (shutdown_pending) {
if (one_process) {
if (is_graceful) {
for (i = 0; i < ap_daemons_limit;) {
for (i = 0; i < ap_daemons_limit; ++i) {
for (j = 0; j < ap_threads_per_child; j++) {
if (!is_graceful) {
static int restart_num = 0;
is_graceful = 0;
if (!one_process) {
unixd_detach();
ap_extended_status = 0;
static void mpmt_pthread_hooks(void)
one_process = 0;
return err;
return NULL;
return err;
return NULL;
return err;
return NULL;
return err;
return NULL;
return err;
if (min_spare_threads <= 0) {
return NULL;
return err;
return NULL;
return err;
return NULL;
return err;
return NULL;
return err;
return NULL;
const char *fname;
return err;
return NULL;
struct ap_thread_mutex {
return mtx;
{ NULL }