child.c revision a2c036f0ca71e35c085b4cd9451a6d3718bc65da
d3ed5b56cb6b58f87ffd125bed48f7668f13de1edirkx/* ====================================================================
893328ef6ff86d0ca27774778d84410353789fb0fielding * The Apache Software License, Version 1.1
842ae4bd224140319ae7feec1872b93dfd491143fielding * Copyright (c) 2000-2003 The Apache Software Foundation. All rights
842ae4bd224140319ae7feec1872b93dfd491143fielding * reserved.
842ae4bd224140319ae7feec1872b93dfd491143fielding * Redistribution and use in source and binary forms, with or without
842ae4bd224140319ae7feec1872b93dfd491143fielding * modification, are permitted provided that the following conditions
893328ef6ff86d0ca27774778d84410353789fb0fielding * 1. Redistributions of source code must retain the above copyright
0202d2114cc6d7042995100519cce45c808c153bnd * notice, this list of conditions and the following disclaimer.
0202d2114cc6d7042995100519cce45c808c153bnd * 2. Redistributions in binary form must reproduce the above copyright
0202d2114cc6d7042995100519cce45c808c153bnd * notice, this list of conditions and the following disclaimer in
0202d2114cc6d7042995100519cce45c808c153bnd * the documentation and/or other materials provided with the
893328ef6ff86d0ca27774778d84410353789fb0fielding * distribution.
893328ef6ff86d0ca27774778d84410353789fb0fielding * 3. The end-user documentation included with the redistribution,
893328ef6ff86d0ca27774778d84410353789fb0fielding * if any, must include the following acknowledgment:
0d50a692ff2ac7bdb42e417737ed86ebf0a41671ben * "This product includes software developed by the
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * Apache Software Foundation (http://www.apache.org/)."
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * Alternately, this acknowledgment may appear in the software itself,
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * if and wherever such third-party acknowledgments normally appear.
928f622b54e87afbbaba6add8aef8066ca16a040wrowe * 4. The names "Apache" and "Apache Software Foundation" must
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * not be used to endorse or promote products derived from this
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * software without prior written permission. For written
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * permission, please contact apache@apache.org.
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * 5. Products derived from this software may not be called "Apache",
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * nor may "Apache" appear in their name, without prior written
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * permission of the Apache Software Foundation.
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * SUCH DAMAGE.
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * ====================================================================
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * This software consists of voluntary contributions made by many
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * individuals on behalf of the Apache Software Foundation. For more
893328ef6ff86d0ca27774778d84410353789fb0fielding * information on the Apache Software Foundation, please see
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * Portions of this software are based upon public domain software
0b7037d0efc1cd510ee12e8a35c982c3f2da0353pquerna * originally written at the National Center for Supercomputing Applications,
90b402e944318ae02afd50911eae6da1910f661dpquerna * University of Illinois, Urbana-Champaign.
928f622b54e87afbbaba6add8aef8066ca16a040wrowe/* shared with mpm_winnt.c */
90b402e944318ae02afd50911eae6da1910f661dpquerna/* used by parent to signal the child to start and exit */
90b402e944318ae02afd50911eae6da1910f661dpquerna/* shared with mpm_winnt.c, but should be private to child.c */
90b402e944318ae02afd50911eae6da1910f661dpquerna/* child_main() should never need to modify is_graceful!?! */
90b402e944318ae02afd50911eae6da1910f661dpquernaextern int volatile is_graceful;
90b402e944318ae02afd50911eae6da1910f661dpquerna/* Queue for managing the passing of COMP_CONTEXTs between
90b402e944318ae02afd50911eae6da1910f661dpquerna * the accept and worker threads.
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantzstatic unsigned int g_blocked_threads = 0;
893328ef6ff86d0ca27774778d84410353789fb0fieldingAP_DECLARE(void) mpm_recycle_completion_context(PCOMP_CONTEXT context)
893328ef6ff86d0ca27774778d84410353789fb0fielding /* Recycle the completion context.
623882f55701a4c5a6bded180f60d86a524ac341sascha * - clear the ptrans pool
5a3fb2c128b4671fb5091eaea8861c759f50a4e6brianp * - put the context on the queue to be consumed by the accept thread
e07615ab3b59412d79eebb8d5b12f488e77c14a7jorton * context->accept_socket may be in a disconnected but reusable
e07615ab3b59412d79eebb8d5b12f488e77c14a7jorton * state so -don't- close it.
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantzAP_DECLARE(PCOMP_CONTEXT) mpm_get_completion_context(void)
893328ef6ff86d0ca27774778d84410353789fb0fielding /* Grab a context off the queue */
c5694b1d7dca4f561ebce416b5ffacf856f825aawrowe /* We failed to grab a context off the queue, consider allocating a
1e5333ef1a0edb888d75c0cdd90b33fa7e89fc31wsanchez * new one out of the child pool. There may be up to ap_threads_per_child
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz * contexts in the system at once.
99d360dcbb5ac2be27694be74cc6124dbadf3315jerenkrantz if (num_completion_contexts >= ap_threads_per_child) {
1e5333ef1a0edb888d75c0cdd90b33fa7e89fc31wsanchez /* All workers are busy, need to wait for one */
1d13cbde60ace1b56ca57b9f0f74168bb1288174trawick static int reported = 0;
80b1e2ff2e3515fdab14675684b2640ceb6ce1c7trawick ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf,
1d13cbde60ace1b56ca57b9f0f74168bb1288174trawick "Server ran out of threads to serve requests. Consider "
9045837071eae7a4b55204a21f31ccee17749af3jerenkrantz "raising the ThreadsPerChild setting");
ab44eb80e084a02a66a58336d6fcfbbe48310439trawick /* Wait for a worker to free a context. Once per second, give
ab44eb80e084a02a66a58336d6fcfbbe48310439trawick * the caller a chance to check for shutdown. If the wait
9045837071eae7a4b55204a21f31ccee17749af3jerenkrantz * succeeds, get the context off the queue. It must be available,
9045837071eae7a4b55204a21f31ccee17749af3jerenkrantz * since there's only one consumer.
893328ef6ff86d0ca27774778d84410353789fb0fielding else /* Hopefully, WAIT_TIMEOUT */
893328ef6ff86d0ca27774778d84410353789fb0fielding /* Allocate another context.
544c23d79a3a7596a3612224ed3ac9fa8372929djerenkrantz * Multiple failures in the next two steps will cause the pchild pool
96e6cafca226a8a2a64a7bbdc634b5b2679c9e0csascha * to 'leak' storage. I don't think this is worth fixing...
e07615ab3b59412d79eebb8d5b12f488e77c14a7jorton context = (PCOMP_CONTEXT) apr_pcalloc(pchild, sizeof(COMP_CONTEXT));
4028d805f3ab215e39bae405d35e001a538bc50eminfrin context->Overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
4028d805f3ab215e39bae405d35e001a538bc50eminfrin /* Hopefully this is a temporary condition ... */
4028d805f3ab215e39bae405d35e001a538bc50eminfrin ap_log_error(APLOG_MARK,APLOG_WARNING, apr_get_os_error(), ap_server_conf,
4028d805f3ab215e39bae405d35e001a538bc50eminfrin "mpm_get_completion_context: CreateEvent failed.");
4028d805f3ab215e39bae405d35e001a538bc50eminfrin /* Create the tranaction pool */
4028d805f3ab215e39bae405d35e001a538bc50eminfrin if ((rv = apr_pool_create(&context->ptrans, pchild)) != APR_SUCCESS) {
4028d805f3ab215e39bae405d35e001a538bc50eminfrin ap_log_error(APLOG_MARK,APLOG_WARNING, rv, ap_server_conf,
4028d805f3ab215e39bae405d35e001a538bc50eminfrin "mpm_get_completion_context: Failed to create the transaction pool.");
f0528865c2e6c22ecc51eeecc496251489029bddjorton /* Got a context from the queue */
if (context)
return APR_SUCCESS;
return (lr);
return NULL;
typedef struct joblist_s {
int sock;
} joblist;
typedef struct globals_s {
int jobcount;
} globals;
static int remove_job(void)
int sock;
return (INVALID_SOCKET);
return (sock);
int csd;
int count_select_errors = 0;
int rc;
int clen;
while (!shutdown_in_progress) {
if (csd < 0) {
int len;
return NULL;
return context;
while (!shutdown_in_progress) {
if (!context) {
if (!context) {
Sleep(0);
Sleep(0);
err_count = 0;
err_count = 0;
if (shutdown_in_progress) {
sizeof(nlsd))) {
if (!shutdown_in_progress) {
int rc;
if (workers_may_exit) {
return NULL;
if (!rc) {
switch (CompKey) {
case IOCP_CONNECTION_ACCEPTED:
case IOCP_SHUTDOWN:
return NULL;
return NULL;
return context;
static int requests_this_child = 0;
conn_rec *c;
if (!context) {
if (ap_max_requests_per_child) {
&disconnected);
if (!disconnected) {
(*thread_cnt)--;
static void create_listener_thread()
int tid;
int threads_created = 0;
int listener_started = 0;
int tid;
int rv;
int cld;
if (!max_requests_per_child_event) {
NULL,
if (!qwait_event) {
for (i = 0; i < ap_threads_per_child; i++) {
int *score_idx;
(void *) i, 0, &tid);
if (child_handles[i] == 0) {
goto shutdown;
*score_idx = i;
#if !APR_HAS_OTHER_CHILD
else if (cld == 0) {
for (i = 0; i < threads_created; i++) {
while (g_blocked_threads > 0) {
for (i=g_blocked_threads; i > 0; i--) {
while (qhead) {
while (threads_created) {
if (threads_created) {
for (i = 0; i < threads_created; i++) {
int *score_idx;