spmt_os2.c revision 8d6907fd72855909a91eadeba1b1f20ab6f23926
97a9a944b5887e91042b019776c41d5dd74557aferikabele/* ====================================================================
97a9a944b5887e91042b019776c41d5dd74557aferikabele * Copyright (c) 1995-1999 The Apache Group. All rights reserved.
a945f35eff8b6a88009ce73de6d4c862ce58de3cslive * Redistribution and use in source and binary forms, with or without
a945f35eff8b6a88009ce73de6d4c862ce58de3cslive * modification, are permitted provided that the following conditions
5a58787efeb02a1c3f06569d019ad81fd2efa06end * 1. Redistributions of source code must retain the above copyright
5a58787efeb02a1c3f06569d019ad81fd2efa06end * notice, this list of conditions and the following disclaimer.
5a58787efeb02a1c3f06569d019ad81fd2efa06end * 2. Redistributions in binary form must reproduce the above copyright
5a58787efeb02a1c3f06569d019ad81fd2efa06end * notice, this list of conditions and the following disclaimer in
5a58787efeb02a1c3f06569d019ad81fd2efa06end * the documentation and/or other materials provided with the
5a58787efeb02a1c3f06569d019ad81fd2efa06end * distribution.
5a58787efeb02a1c3f06569d019ad81fd2efa06end * 3. All advertising materials mentioning features or use of this
5a58787efeb02a1c3f06569d019ad81fd2efa06end * software must display the following acknowledgment:
5a58787efeb02a1c3f06569d019ad81fd2efa06end * "This product includes software developed by the Apache Group
5a58787efeb02a1c3f06569d019ad81fd2efa06end * for use in the Apache HTTP server project (http://www.apache.org/)."
5a58787efeb02a1c3f06569d019ad81fd2efa06end * 4. The names "Apache Server" and "Apache Group" must not be used to
a63f0ab647ad2ab72efc9bea7a66e24e9ebc5cc2nd * endorse or promote products derived from this software without
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd * prior written permission. For written permission, please contact
ad74a0524a06bfe11b7de9e3b4ce7233ab3bd3f7nd * apache@apache.org.
ad74a0524a06bfe11b7de9e3b4ce7233ab3bd3f7nd * 5. Products derived from this software may not be called "Apache"
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd * nor may "Apache" appear in their names without prior written
5a58787efeb02a1c3f06569d019ad81fd2efa06end * permission of the Apache Group.
5a58787efeb02a1c3f06569d019ad81fd2efa06end * 6. Redistributions of any form whatsoever must retain the following
5a58787efeb02a1c3f06569d019ad81fd2efa06end * acknowledgment:
5a58787efeb02a1c3f06569d019ad81fd2efa06end * "This product includes software developed by the Apache Group
5a58787efeb02a1c3f06569d019ad81fd2efa06end * for use in the Apache HTTP server project (http://www.apache.org/)."
06ba4a61654b3763ad65f52283832ebf058fdf1cslive * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
9b6a3a558cc90ffdaa0b50bd02546ffec424ded7slive * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9b6a3a558cc90ffdaa0b50bd02546ffec424ded7slive * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
9b6a3a558cc90ffdaa0b50bd02546ffec424ded7slive * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
9b6a3a558cc90ffdaa0b50bd02546ffec424ded7slive * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9b6a3a558cc90ffdaa0b50bd02546ffec424ded7slive * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
9b6a3a558cc90ffdaa0b50bd02546ffec424ded7slive * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9b6a3a558cc90ffdaa0b50bd02546ffec424ded7slive * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
97a9a944b5887e91042b019776c41d5dd74557aferikabele * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
f8396ed8364b56ec8adeaa49cac35a929758a29eslive * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
97a9a944b5887e91042b019776c41d5dd74557aferikabele * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
f8396ed8364b56ec8adeaa49cac35a929758a29eslive * OF THE POSSIBILITY OF SUCH DAMAGE.
f8396ed8364b56ec8adeaa49cac35a929758a29eslive * ====================================================================
5a58787efeb02a1c3f06569d019ad81fd2efa06end * This software consists of voluntary contributions made by many
5a58787efeb02a1c3f06569d019ad81fd2efa06end * individuals on behalf of the Apache Group and was originally based
a63f0ab647ad2ab72efc9bea7a66e24e9ebc5cc2nd * on public domain software written at the National Center for
5a58787efeb02a1c3f06569d019ad81fd2efa06end * Supercomputing Applications, University of Illinois, Urbana-Champaign.
deeee6bb6fd94c0ba5f3730b58abd9d299c89ccdnd * For more information on the Apache Group and the Apache HTTP server
117c1f888a14e73cdd821dc6c23eb0411144a41cnd * project, please see <http://www.apache.org/>.
5a58787efeb02a1c3f06569d019ad81fd2efa06end/* config globals */
06ba4a61654b3763ad65f52283832ebf058fdf1cslivestatic int ap_extended_status = 0;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive * The max child slot ever assigned, preserved across restarts. Necessary
06ba4a61654b3763ad65f52283832ebf058fdf1cslive * to deal with MaxClients changes across SIGUSR1 restarts. We use this
92510838f2eb125726e15c5eb4f7a23c7a0396e4slive * value to optimize routines that have to scan the entire scoreboard.
9b6a3a558cc90ffdaa0b50bd02546ffec424ded7slive/* *Non*-shared http_main globals... */
8a6d5edcb07aeccca7afba02a17dd6904d6b206ctrawick/* one_process --- debugging mode variable; can be set from the command line
8a6d5edcb07aeccca7afba02a17dd6904d6b206ctrawick * with the -X flag. If set, this gets you the child_main loop running
8a6d5edcb07aeccca7afba02a17dd6904d6b206ctrawick * in the process which originally started up (no detach, no make_child),
8a6d5edcb07aeccca7afba02a17dd6904d6b206ctrawick * which is a pretty nice debugging environment. (You'll get a SIGHUP
8a6d5edcb07aeccca7afba02a17dd6904d6b206ctrawick * early in standalone_main; just continue through. This is the server
8a6d5edcb07aeccca7afba02a17dd6904d6b206ctrawick * trying to kill off any child processes which it might have lying
8a6d5edcb07aeccca7afba02a17dd6904d6b206ctrawick * around --- Apache doesn't keep track of their pids, it just sends
8a6d5edcb07aeccca7afba02a17dd6904d6b206ctrawick * SIGHUP to the process group, ignoring it in the root process.
8a6d5edcb07aeccca7afba02a17dd6904d6b206ctrawick * Continue through and you'll be fine.).
8a6d5edcb07aeccca7afba02a17dd6904d6b206ctrawickstatic int one_process = 0;
8a6d5edcb07aeccca7afba02a17dd6904d6b206ctrawick/* used to maintain list of children which aren't part of the scoreboard */
8a6d5edcb07aeccca7afba02a17dd6904d6b206ctrawickstatic ap_context_t *pconf; /* Pool for config stuff */
8a6d5edcb07aeccca7afba02a17dd6904d6b206ctrawick ap_context_t *pchild; /* Pool for httpd child stuff */
8a6d5edcb07aeccca7afba02a17dd6904d6b206ctrawickstatic struct thread_globals **ppthread_globals = NULL;
92510838f2eb125726e15c5eb4f7a23c7a0396e4slive#define THREAD_GLOBAL(gvar) ((*ppthread_globals)->gvar)
ea8a727ff298d2f5368b55b7ae8d87091ae106e7nd ap_scoreboard_image = (scoreboard *) malloc(SCOREBOARD_SIZE);
ea8a727ff298d2f5368b55b7ae8d87091ae106e7nd ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
8a6d5edcb07aeccca7afba02a17dd6904d6b206ctrawick "Ouch! Out of memory reiniting scoreboard!");
9b6a3a558cc90ffdaa0b50bd02546ffec424ded7slive/* a clean exit from a child with proper cleanup */
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd ap_scoreboard_image->servers[THREAD_GLOBAL(child_num)].thread_retval = code;
#if defined(USE_OS2SEM_SERIALIZED_ACCEPT)
return APR_SUCCESS;
if (rc != 0) {
if (rc != 0) {
static void accept_mutex_on(void)
if (rc != 0) {
static void accept_mutex_off(void)
if (rc != 0) {
#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 old_status;
if (child_num < 0)
if (ap_extended_status) {
return old_status;
if (child_num < 0)
#if !defined(HAVE_GETTIMEOFDAY)
#ifdef HAVE_TIMES
#if !defined(HAVE_GETTIMEOFDAY)
#ifdef HAVE_TIMES
long int bs = 0;
if (r->sent_bodyct)
#ifdef HAVE_TIMES
for (i = 0; i < max_daemons_limit; ++i)
#ifndef INTERVAL_OF_WRITABLE_PROBES
static int wait_or_timeout_counter;
int ret;
#ifdef HAS_OTHER_CHILD
tid = 0;
if (ret == 0) {
return tid;
#if defined(NSIG)
static void siglist_init(void)
int sig;
#ifdef SIGHUP
#ifdef SIGINT
#ifdef SIGQUIT
#ifdef SIGILL
#ifdef SIGTRAP
#ifdef SIGIOT
#ifdef SIGABRT
#ifdef SIGEMT
#ifdef SIGFPE
#ifdef SIGKILL
#ifdef SIGBUS
#ifdef SIGSEGV
#ifdef SIGSYS
#ifdef SIGPIPE
#ifdef SIGALRM
#ifdef SIGTERM
#ifdef SIGUSR1
#ifdef SIGUSR2
#ifdef SIGCLD
#ifdef SIGCHLD
#ifdef SIGPWR
#ifdef SIGWINCH
#ifdef SIGURG
#ifdef SIGPOLL
#ifdef SIGIO
#ifdef SIGSTOP
#ifdef SIGTSTP
#ifdef SIGCONT
#ifdef SIGTTIN
#ifdef SIGTTOU
#ifdef SIGVTALRM
#ifdef SIGPROF
#ifdef SIGXCPU
#ifdef SIGXFSZ
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
if (!one_process) {
#ifdef SIGBUS
#ifdef SIGABORT
#ifdef SIGABRT
#ifdef SIGILL
#ifdef SIGXCPU
#ifdef SIGXFSZ
#ifdef SIGHUP
#ifdef SIGUSR1
#ifdef SIGPIPE
int ap_graceful_stop_signalled(void)
ap_scoreboard_image->global.running_generation != ap_scoreboard_image->parent[THREAD_GLOBAL(child_num)].generation) {
int numfds = 0;
numfds++;
int requests_this_child = 0;
while (!ap_graceful_stop_signalled()) {
int srv;
if ((ap_max_requests_per_child > 0
clean_child_exit(0);
if (srv <= 0)
if (!lr) {
clean_child_exit(0);
switch (rv) {
#ifdef EPROTO
case EPROTO:
#ifdef ECONNABORTED
case ECONNABORTED:
#ifdef ECONNRESET
case ECONNRESET:
#ifdef ETIMEDOUT
case ETIMEDOUT:
#ifdef EHOSTUNREACH
case EHOSTUNREACH:
#ifdef ENETUNREACH
case ENETUNREACH:
if (ap_graceful_stop_signalled()) {
clean_child_exit(0);
clean_child_exit(0);
if (one_process) {
#ifdef SIGQUIT
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, s, "_beginthread: Unable to create new thread");
#ifndef MAX_SPAWN_RATE
static int hold_off_on_exponential_spawning;
static void perform_idle_server_maintenance(void)
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) {
tid);
case SIGTERM:
case SIGHUP:
case SIGUSR1:
case SIGKILL:
#ifdef SYS_SIGLIST
#ifdef WCOREDUMP
#ifdef WCOREDUMP
server_conf = s;
if (!is_graceful) {
set_signals();
if (!is_graceful) {
int child_slot;
if (tid >= 0) {
if (child_slot >= 0) {
#ifdef HAS_OTHER_CHILD
else if (is_graceful) {
else if (remaining_children_to_start) {
if (shutdown_pending) {
int slot;
if (rc == 0) {
if (rc) {
if (one_process) {
if (is_graceful) {
for (i = 0; i < ap_daemons_limit; ++i) {
for (i = 0; i < ap_daemons_limit; ++i) {
for (i = 0; i < ap_daemons_limit; ++i) {
if (!is_graceful) {
is_graceful = 0;
ap_extended_status = 0;
static void spmt_os2_hooks(void)
INIT_SIGLIST();
return err;
return NULL;
return err;
return NULL;
return err;
if (ap_daemons_min_free <= 0) {
return NULL;
return err;
return NULL;
return err;
return NULL;
return err;
return NULL;
const char *fname;
return err;
return NULL;
const char *value)
{ NULL }