dexter.c revision 6f984345bbfa9342dde1f2b7b8c35b7987d078af
842ae4bd224140319ae7feec1872b93dfd491143fielding/* ====================================================================
842ae4bd224140319ae7feec1872b93dfd491143fielding * The Apache Software License, Version 1.1
842ae4bd224140319ae7feec1872b93dfd491143fielding * Copyright (c) 2000 The Apache Software Foundation. All rights
842ae4bd224140319ae7feec1872b93dfd491143fielding * reserved.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * Redistribution and use in source and binary forms, with or without
04891cf70e0bfc38bfb027541dc821f04c754ff7nd * modification, are permitted provided that the following conditions
04891cf70e0bfc38bfb027541dc821f04c754ff7nd * 1. Redistributions of source code must retain the above copyright
04891cf70e0bfc38bfb027541dc821f04c754ff7nd * notice, this list of conditions and the following disclaimer.
04891cf70e0bfc38bfb027541dc821f04c754ff7nd * 2. Redistributions in binary form must reproduce the above copyright
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * notice, this list of conditions and the following disclaimer in
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * the documentation and/or other materials provided with the
3568de757bac0b47256647504c186d17ca272f85rbb * distribution.
3568de757bac0b47256647504c186d17ca272f85rbb * 3. The end-user documentation included with the redistribution,
3568de757bac0b47256647504c186d17ca272f85rbb * if any, must include the following acknowledgment:
3568de757bac0b47256647504c186d17ca272f85rbb * "This product includes software developed by the
3568de757bac0b47256647504c186d17ca272f85rbb * Apache Software Foundation (http://www.apache.org/)."
3568de757bac0b47256647504c186d17ca272f85rbb * Alternately, this acknowledgment may appear in the software itself,
3568de757bac0b47256647504c186d17ca272f85rbb * if and wherever such third-party acknowledgments normally appear.
3568de757bac0b47256647504c186d17ca272f85rbb * 4. The names "Apache" and "Apache Software Foundation" must
3568de757bac0b47256647504c186d17ca272f85rbb * not be used to endorse or promote products derived from this
3568de757bac0b47256647504c186d17ca272f85rbb * software without prior written permission. For written
3568de757bac0b47256647504c186d17ca272f85rbb * permission, please contact apache@apache.org.
3568de757bac0b47256647504c186d17ca272f85rbb * 5. Products derived from this software may not be called "Apache",
3568de757bac0b47256647504c186d17ca272f85rbb * nor may "Apache" appear in their name, without prior written
3568de757bac0b47256647504c186d17ca272f85rbb * permission of the Apache Software Foundation.
3568de757bac0b47256647504c186d17ca272f85rbb * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
3568de757bac0b47256647504c186d17ca272f85rbb * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
3568de757bac0b47256647504c186d17ca272f85rbb * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3568de757bac0b47256647504c186d17ca272f85rbb * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
3568de757bac0b47256647504c186d17ca272f85rbb * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3568de757bac0b47256647504c186d17ca272f85rbb * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3568de757bac0b47256647504c186d17ca272f85rbb * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
3568de757bac0b47256647504c186d17ca272f85rbb * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3568de757bac0b47256647504c186d17ca272f85rbb * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
3568de757bac0b47256647504c186d17ca272f85rbb * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
3568de757bac0b47256647504c186d17ca272f85rbb * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3568de757bac0b47256647504c186d17ca272f85rbb * SUCH DAMAGE.
3568de757bac0b47256647504c186d17ca272f85rbb * ====================================================================
3568de757bac0b47256647504c186d17ca272f85rbb * This software consists of voluntary contributions made by many
3568de757bac0b47256647504c186d17ca272f85rbb * individuals on behalf of the Apache Software Foundation. For more
3568de757bac0b47256647504c186d17ca272f85rbb * information on the Apache Software Foundation, please see
3568de757bac0b47256647504c186d17ca272f85rbb * Portions of this software are based upon public domain software
3568de757bac0b47256647504c186d17ca272f85rbb * originally written at the National Center for Supercomputing Applications,
3568de757bac0b47256647504c186d17ca272f85rbb * University of Illinois, Urbana-Champaign.
f0e395a55abfcad3d2bd7c63470003b08a93d567nd * Actual definitions of config globals
98fb535f829e2a95aabd82420931f476661fa8e3jortonstatic int threads_to_start = 0; /* Worker threads per child */
7cd5419264796cfeaf8215383cf0f89130a81fectrawickstatic int min_spare_threads = 0;
7cd5419264796cfeaf8215383cf0f89130a81fectrawickstatic int max_spare_threads = 0;
7cd5419264796cfeaf8215383cf0f89130a81fectrawickstatic int max_threads = 0;
7cd5419264796cfeaf8215383cf0f89130a81fectrawickAP_DECLARE_DATA const char *ap_scoreboard_fname=NULL;
7cd5419264796cfeaf8215383cf0f89130a81fectrawickstatic int workers_may_exit = 0;
41634f717c623556a16b27b25d7d909a66fe20f8wrowestatic int num_listenfds = 0;
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantzstruct ap_ctable ap_child_table[HARD_SERVER_LIMIT];
3568de757bac0b47256647504c186d17ca272f85rbb * The max child slot ever assigned, preserved across restarts. Necessary
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz * to deal with NumServers changes across SIGWINCH restarts. We use this
3568de757bac0b47256647504c186d17ca272f85rbb * value to optimize routines that have to scan the entire child table.
3568de757bac0b47256647504c186d17ca272f85rbb * XXX - It might not be worth keeping this code in. There aren't very
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * many child processes in this MPM.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* *Non*-shared http_main globals... */
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz/* one_process --- debugging mode variable; can be set from the command line
24b534291150023e6b68eca89ddd33e475ccddc0wrowe * with the -X flag. If set, this gets you the child_main loop running
3568de757bac0b47256647504c186d17ca272f85rbb * in the process which originally started up (no detach, no make_child),
24b534291150023e6b68eca89ddd33e475ccddc0wrowe * which is a pretty nice debugging environment. (You'll get a SIGHUP
3568de757bac0b47256647504c186d17ca272f85rbb * early in standalone_main; just continue through. This is the server
24b534291150023e6b68eca89ddd33e475ccddc0wrowe * trying to kill off any child processes which it might have lying
24b534291150023e6b68eca89ddd33e475ccddc0wrowe * around --- Apache doesn't keep track of their pids, it just sends
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz * SIGHUP to the process group, ignoring it in the root process.
3568de757bac0b47256647504c186d17ca272f85rbb * Continue through and you'll be fine.).
3568de757bac0b47256647504c186d17ca272f85rbbstatic int one_process = 0;
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantzstatic apr_pool_t *pchild; /* Pool for httpd child stuff */
3568de757bac0b47256647504c186d17ca272f85rbbstatic apr_pool_t *thread_pool_parent; /* Parent of per-thread pools */
3568de757bac0b47256647504c186d17ca272f85rbbstatic unsigned int my_pid; /* Linux getpid() doesn't work except in
3568de757bac0b47256647504c186d17ca272f85rbb main thread. Use this instead */
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz/* Keep track of the number of worker threads currently active */
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantzstatic pthread_mutex_t worker_thread_count_mutex;
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantzstatic int worker_thread_free_ids[HARD_THREAD_LIMIT];
3568de757bac0b47256647504c186d17ca272f85rbb/* Keep track of the number of idle worker threads */
3568de757bac0b47256647504c186d17ca272f85rbb/* Locks for accept serialization */
3568de757bac0b47256647504c186d17ca272f85rbb#endif /* NO_SERIALIZED_ACCEPT */
3568de757bac0b47256647504c186d17ca272f85rbbstatic const char *lock_fname;
239f998fbee5ac5b114b965bb76e217cce0003edstoddard/* a clean exit from a child with proper cleanup */
3568de757bac0b47256647504c186d17ca272f85rbb/* handle all varieties of core dumping signals */
6653a33e820463abd4f81915b7a1eba0f602e200brianp /* At this point we've got sig blocked, because we're still inside
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm * the signal handler. When we leave the signal handler it will
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm * be unblocked, and we'll take the signal... and coredump or whatever
cd8f8c995d415473f3bfb0b329b2450f2a722c3atrawick * is appropriate for this particular Unix. In addition the parent
36c8049de63c446926139936c3d195330a0539cetrawick * will see the real signal we received -- whereas if we called
3568de757bac0b47256647504c186d17ca272f85rbb * abort() here, the parent would only see SIGABRT.
dd028aa8111afb6534fece555e8c2d408894671etrawick/*****************************************************************
6653a33e820463abd4f81915b7a1eba0f602e200brianp * Connection structures and accounting...
6653a33e820463abd4f81915b7a1eba0f602e200brianp/* volatile just in case */
6653a33e820463abd4f81915b7a1eba0f602e200brianpstatic int volatile shutdown_pending;
6653a33e820463abd4f81915b7a1eba0f602e200brianpstatic int volatile restart_pending;
6653a33e820463abd4f81915b7a1eba0f602e200brianpstatic int volatile is_graceful;
6653a33e820463abd4f81915b7a1eba0f602e200brianp * ap_start_shutdown() and ap_start_restart(), below, are a first stab at
6653a33e820463abd4f81915b7a1eba0f602e200brianp * functions to initiate shutdown or restart without relying on signals.
6653a33e820463abd4f81915b7a1eba0f602e200brianp * Previously this was initiated in sig_term() and restart() signal handlers,
6653a33e820463abd4f81915b7a1eba0f602e200brianp * but we want to be able to start a shutdown/restart from other sources --
6653a33e820463abd4f81915b7a1eba0f602e200brianp * e.g. on Win32, from the service manager. Now the service manager can
6653a33e820463abd4f81915b7a1eba0f602e200brianp * call ap_start_shutdown() or ap_start_restart() as appropiate. Note that
6653a33e820463abd4f81915b7a1eba0f602e200brianp * these functions can also be called by the child processes, since global
cd8f8c995d415473f3bfb0b329b2450f2a722c3atrawick * variables are no longer used to pass on the required action to the parent.
cd8f8c995d415473f3bfb0b329b2450f2a722c3atrawick * These should only be called from the parent process itself, since the
239f998fbee5ac5b114b965bb76e217cce0003edstoddard * parent process will use the shutdown_pending and restart_pending variables
3568de757bac0b47256647504c186d17ca272f85rbb * to determine whether to shutdown or restart. The child process should
3568de757bac0b47256647504c186d17ca272f85rbb * call signal_parent() directly to tell the parent to die -- this will
3568de757bac0b47256647504c186d17ca272f85rbb * cause neither of those variable to be set, which the parent will
12901074f5d6b36d08be84d8637b6f2c21e0da26trawick * assume means something serious is wrong (which it will be, for the
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard * child to force an exit) and so do an exit anyway.
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantzstatic void ap_start_shutdown(void)
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard /* Um, is this _probably_ not an error, if the user has
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * tried to do a shutdown twice quickly, so we won't
f2e009134c7e279f99dfca5bd421f721bf1f7840jorton * worry about reporting it.
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard/* do a graceful restart if graceful == 1 */
9f979f5c8061f6f6f560d1824e0e378ff5b91931rpluem /* Probably not an error - don't bother reporting it */
9f979f5c8061f6f6f560d1824e0e378ff5b91931rpluem apr_kill_cleanup(pconf, NULL, ap_cleanup_shared_mem);
3568de757bac0b47256647504c186d17ca272f85rbbstatic void set_signals(void)
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGSEGV)");
dd028aa8111afb6534fece555e8c2d408894671etrawick ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGBUS)");
3cbd177a6c885562f9ad0cf11695f044489c881dgregames ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGABORT)");
5a0f707b48da7703cbe6bc087f13a6735b1c742dgregames ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGABRT)");
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGILL)");
7cd5419264796cfeaf8215383cf0f89130a81fectrawick ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGTERM)");
7cd5419264796cfeaf8215383cf0f89130a81fectrawick ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGINT)");
7cd5419264796cfeaf8215383cf0f89130a81fectrawick ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXCPU)");
7cd5419264796cfeaf8215383cf0f89130a81fectrawick ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXFSZ)");
7cd5419264796cfeaf8215383cf0f89130a81fectrawick ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGPIPE)");
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard /* we want to ignore HUPs and WINCH while we're busy processing one */
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGHUP)");
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGWINCH)");
7cd5419264796cfeaf8215383cf0f89130a81fectrawick#endif /* SIGBUS */
7cd5419264796cfeaf8215383cf0f89130a81fectrawick#endif /* SIGABORT */
3568de757bac0b47256647504c186d17ca272f85rbb#endif /* SIGABRT */
72b6f1cf3e616473e1c26464b3193b13c2c09e87brianp#endif /* SIGILL */
3568de757bac0b47256647504c186d17ca272f85rbb#endif /* SIGXCPU */
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard#endif /* SIGXFSZ */
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard#endif /* SIGHUP */
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz#endif /* SIGWINCH */
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz#endif /* SIGPIPE */
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard/*****************************************************************
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard * Here follows a long bunch of generic server bookkeeping stuff...
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard /* XXX - Does this really work? - Manoj */
3568de757bac0b47256647504c186d17ca272f85rbb/*****************************************************************
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard * Child process main loop.
4a13940dc2990df0a798718d3a3f9cf1566c2217bjhstatic void process_socket(apr_pool_t *p, apr_socket_t *sock, long conn_id)
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard if ((rv = apr_get_os_sock(&csd, sock)) != APR_SUCCESS) {
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, "apr_get_os_sock");
663237d6bcc59ac0997d71d48a1baa55fa29a3d8jim ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, NULL,
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard "new file descriptor %d is too large; you probably need "
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard "to rebuild Apache with a larger FD_SETSIZE "
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard "(currently %d)",
4a13940dc2990df0a798718d3a3f9cf1566c2217bjh current_conn = ap_new_connection(p, ap_server_conf, sock, conn_id);
4a13940dc2990df0a798718d3a3f9cf1566c2217bjhstatic void *worker_thread(void *);
3568de757bac0b47256647504c186d17ca272f85rbb/* Starts a thread as long as we're below max_threads */
663237d6bcc59ac0997d71d48a1baa55fa29a3d8jimstatic int start_thread(void)
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard if ((rc = pthread_create(&thread, &worker_thread_attr, worker_thread,
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard ap_log_error(APLOG_MARK, APLOG_ALERT, rc, ap_server_conf,
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard "pthread_create: unable to create worker thread");
3568de757bac0b47256647504c186d17ca272f85rbb /* In case system resources are maxxed out, we don't want
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard Apache running away with the CPU trying to fork over and
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz over and over again if we exit. */
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard static int reported = 0;
3568de757bac0b47256647504c186d17ca272f85rbb ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, ap_server_conf,
cd8f8c995d415473f3bfb0b329b2450f2a722c3atrawick "server reached MaxThreadsPerChild setting, consider raising the"
cd8f8c995d415473f3bfb0b329b2450f2a722c3atrawick " MaxThreadsPerChild or NumServers settings");
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz pthread_mutex_unlock(&worker_thread_count_mutex);
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard/* Sets workers_may_exit if we received a character on the pipe_of_death */
3568de757bac0b47256647504c186d17ca272f85rbbstatic void check_pipe_of_death(void)
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard /* It lost the lottery. It must continue to suffer
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard * through a life of servitude. */
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard /* It won the lottery (or something else is very
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard * wrong). Embrace death with open arms. */
cd8f8c995d415473f3bfb0b329b2450f2a722c3atrawick/* idle_thread_count should be incremented before starting a worker_thread */
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz apr_pool_t *ptrans; /* Pool for per-transaction stuff */
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard long conn_id = child_num * HARD_THREAD_LIMIT + thread_num;
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick for(n=0 ; n <= num_listenfds ; ++n)
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick apr_add_poll_socket(pollset, listenfds[n], APR_POLLIN);
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick while (1) {
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick workers_may_exit |= (max_requests_per_child != 0) && (requests_this_child <= 0);
2e7f1d7da527c09e717251e186deffe55e6fbd0ftrawick ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm "apr_lock failed. Attempting to shutdown "
3568de757bac0b47256647504c186d17ca272f85rbb "process gracefully.");
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm /* apr_poll() will only return errors in catastrophic
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm * circumstances. Let's try exiting gracefully, for now. */
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm ap_log_error(APLOG_MARK, APLOG_ERR, srv, (const server_rec *)
36c8049de63c446926139936c3d195330a0539cetrawick /* A process got a signal on the shutdown pipe. Check if we're
e8f95a682820a599fe41b22977010636be5c2717jim * the lucky process to die. */
cb97ae2ff6969c2789b8e03f1bc4187fa73b6bafwrowe /* find a listener */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* XXX: Should we check for POLLERR? */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick apr_get_revents(&event, listenfds[curr_pollfd], pollset);
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick if ((rv = apr_accept(&csd, sd, ptrans)) != APR_SUCCESS) {
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, "apr_accept");
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick "apr_unlock failed. Attempting to shutdown "
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick "process gracefully.");
f886987cd0bd4220c14043c4d9be77ec22902e73trawick ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick "apr_unlock failed. Attempting to shutdown "
f886987cd0bd4220c14043c4d9be77ec22902e73trawick "process gracefully.");
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick worker_thread_free_ids[worker_thread_count] = thread_num;
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* All the threads have exited, now finish the shutdown process
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm * by signalling the sigwait thread */
36c8049de63c446926139936c3d195330a0539cetrawick /*stuff to do before we switch id's, so we have permissions.*/
e8f95a682820a599fe41b22977010636be5c2717jim rv = SAFE_ACCEPT(apr_child_init_lock(&accept_mutex, lock_fname,
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick "Couldn't initialize cross-process lock in child");
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /*done with init critical section */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* All threads should mask signals out, accoring to sigwait(2) man page */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick if (sigprocmask(SIG_SETMASK, &sig_mask, NULL) != 0) {
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf, "sigprocmask");
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick if ((rv = pthread_sigmask(SIG_SETMASK, &sig_mask, NULL)) != 0) {
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick "pthread_sigmask");
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* Set up the pollfd array */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick listenfds = apr_pcalloc(pchild, sizeof(*listenfds) * (num_listenfds + 1));
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick apr_socket_from_file(&listenfds[0], pipe_of_death_in);
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick for (lr = ap_listeners, i = 1; i <= num_listenfds; lr = lr->next, ++i)
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* Setup worker threads */
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm for (i = 0; i < max_threads; i++) {
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick pthread_mutex_init(&thread_pool_parent_mutex, NULL);
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick pthread_mutex_init(&worker_thread_count_mutex, NULL);
44d2e75323651320b480d8bc2f098448a08de4fcwrowe pthread_attr_setdetachstate(&worker_thread_attr, &on);
44d2e75323651320b480d8bc2f098448a08de4fcwrowe pthread_attr_setdetachstate(&worker_thread_attr, PTHREAD_CREATE_DETACHED);
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* We are creating worker threads right now */
2e7f1d7da527c09e717251e186deffe55e6fbd0ftrawick for (i=0; i < threads_to_start; i++) {
2e7f1d7da527c09e717251e186deffe55e6fbd0ftrawick /* start_thread shouldn't fail here */
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe /* This thread will be the one responsible for handling signals */
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf,
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantzstatic int make_child(server_rec *s, int slot, time_t now)
98fb535f829e2a95aabd82420931f476661fa8e3jorton "fork: Unable to fork new process");
98fb535f829e2a95aabd82420931f476661fa8e3jorton /* In case system resources are maxxed out, we don't want
3568de757bac0b47256647504c186d17ca272f85rbb Apache running away with the CPU trying to fork over and
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz over and over again. */
3568de757bac0b47256647504c186d17ca272f85rbb return -1;
0cb6873985efbf0cc9644114925df6baa4b32d5awrowe /* By default, AIX binds to a single processor. This bit unbinds
0cb6873985efbf0cc9644114925df6baa4b32d5awrowe children which will then bind to another CPU.
0cb6873985efbf0cc9644114925df6baa4b32d5awrowe int status = bindprocessor(BINDPROCESS, (int)getpid(),
85c5af648e9f414bd4f157490766d2fd5515a9f5rpluem ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, errno,
0cb6873985efbf0cc9644114925df6baa4b32d5awrowe ap_server_conf, "processor unbind failed %d", status);
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz /* XXX - For an unthreaded server, a signal handler will be necessary
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz apr_signal(SIGTERM, just_die);
3568de757bac0b47256647504c186d17ca272f85rbb /* else */
3568de757bac0b47256647504c186d17ca272f85rbb/* start up a bunch of children */
7cd5419264796cfeaf8215383cf0f89130a81fectrawick for (i = 0; number_to_start && i < num_daemons; ++i) {
3d96ee83babeec32482c9082c9426340cee8c44dwrowe * spawn_rate is the number of children that will be spawned on the
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * next maintenance cycle if there aren't enough servers. It is
302dc1f7b3feee23a91ad8f3cf3cb2edd95a557bmanoj * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz * without the need to spawn.
static void perform_child_maintenance(void)
int free_length;
free_length = 0;
for (i = 0; i < num_daemons; ++i) {
++free_length;
last_non_dead = i;
if (free_length > 0) {
for (i = 0; i < free_length; ++i) {
int child_slot;
for (i = 0; i < ap_max_daemons_limit; ++i) {
child_slot = i;
for (j = 0; j < HARD_THREAD_LIMIT; j++) {
if (child_slot >= 0) {
else if (is_graceful) {
else if (remaining_children_to_start) {
ap_server_conf = s;
!= APR_SUCCESS) {
ap_server_conf = s;
my_pid);
if (!is_graceful) {
if (!is_graceful) {
for (i = 0; i < HARD_SERVER_LIMIT; i++) {
set_signals();
if (!is_graceful) {
if (shutdown_pending) {
if (one_process) {
if (is_graceful) {
for (i = 0; i < num_daemons; ++i) {
for (i = 0; i < num_daemons;) {
static int restart_num = 0;
int no_detach = 0;
is_graceful = 0;
apr_detach();
one_process = 0;
return err;
return NULL;
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;
{ NULL }