mpmt_os2_child.c revision 1fbf6ba0f5207e6637b49f9a9dfcc779bbe952a9
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
*
* Portions of this software are based upon public domain software
* originally written at the National Center for Supercomputing Applications,
* University of Illinois, Urbana-Champaign.
*/
#define CORE_PRIVATE
#define INCL_NOPMAPI
#define INCL_DOS
#define INCL_DOSERRORS
#include "ap_config.h"
#include "httpd.h"
#include "mpm_default.h"
#include "http_main.h"
#include "http_log.h"
#include "http_config.h"
#include "http_core.h" /* for get_remote_host */
#include "http_connection.h"
#include "mpm.h"
#include "ap_mpm.h"
#include "ap_listen.h"
#include "apr_portable.h"
#include "apr_poll.h"
#include "mpm_common.h"
#include "apr_strings.h"
#include <os2.h>
#include <process.h>
/* XXXXXX move these to header file private to this MPM */
/* We don't need many processes,
* they're only for redundancy in the event of a crash
*/
#define HARD_SERVER_LIMIT 10
/* Limit on the total number of threads per process
*/
#ifndef HARD_THREAD_LIMIT
#define HARD_THREAD_LIMIT 256
#endif
#define ID_FROM_CHILD_THREAD(c, t) ((c * HARD_THREAD_LIMIT) + t)
typedef struct {
#define WORKTYPE_CONN 0
#define WORKTYPE_EXIT 1
static int child_slot;
static int shutdown_pending = 0;
extern int ap_my_generation;
static int volatile is_graceful = 1;
/* grab some MPM globals */
extern int ap_min_spare_threads;
extern int ap_max_spare_threads;
extern HMTX ap_mpm_accept_mutex;
static void worker_main(void *vpArg);
static void clean_child_exit(int code);
static void set_signals();
static void server_maintenance(void *vpArg);
static void clean_child_exit(int code)
{
if (pchild) {
}
}
{
int requests_this_child = 0;
unsigned long ulTimes;
int num_listeners;
void *sb_mem;
/* Stop Ctrl-C/Ctrl-Break signals going to child processes */
set_signals();
/* Create pool for child */
/* Create an event semaphore used to trigger other threads to shutdown */
if (rc) {
"unable to create shutdown semaphore, exiting");
}
/* Gain access to the scoreboard. */
if (rc) {
"scoreboard not readable in child, exiting");
}
/* Gain access to the accpet mutex */
if (rc) {
"accept mutex couldn't be accessed in child, exiting");
}
/* Find our pid in the scoreboard so we know what slot our parent allocated us */
for (child_slot = 0; ap_scoreboard_image->parent[child_slot].pid != my_pid && child_slot < HARD_SERVER_LIMIT; child_slot++);
if (child_slot == HARD_SERVER_LIMIT) {
"child pid not found in scoreboard, exiting");
}
/* Set up an OS/2 queue for passing connections & termination requests
* to worker threads
*/
if (rc) {
"unable to create work queue, exiting");
}
/* Create initial pool of worker threads */
for (c = 0; c < ap_min_spare_threads; c++) {
// ap_scoreboard_image->servers[child_slot][c].tid = _beginthread(worker_main, NULL, 128*1024, (void *)c);
}
/* Start maintenance thread */
/* Set up poll */
}
}
/* Main connection accept loop */
do {
if (num_listeners == 1) {
} else {
if (shutdown_pending) {
break;
}
if (rv == APR_SUCCESS) {
}
if (rv == APR_SUCCESS) {
}
do {
if (event == APR_POLLIN) {
break;
}
if (!lr) {
lr = ap_listeners;
}
continue;
}
}
}
if (rv != APR_SUCCESS) {
if (!APR_STATUS_IS_EINTR(rv)) {
"apr_socket_accept");
}
} else {
}
break;
if (is_graceful) {
char someleft;
/* tell our worker threads to exit */
for (c=0; c<HARD_THREAD_LIMIT; c++) {
}
}
do {
someleft = 0;
for (c=0; c<HARD_THREAD_LIMIT; c++) {
someleft = 1;
DosSleep(1000);
break;
}
}
} while (someleft);
} else {
for (c=0; c<HARD_THREAD_LIMIT; c++) {
}
}
}
}
void add_worker()
{
int thread_slot;
/* Find a free thread slot */
break;
}
}
}
PVOID p)
{
int c;
return XCPT_CONTINUE_SEARCH;
}
"caught exception in worker thread, initiating child shutdown pid=%d", getpid());
for (c=0; c<HARD_THREAD_LIMIT; c++) {
break;
}
}
/* Shut down process ASAP, it could be quite unhealthy & leaking resources */
shutdown_pending = 1;
DosUnwindException(UNWIND_ALL, 0, 0);
}
return XCPT_CONTINUE_SEARCH;
}
static void worker_main(void *vpArg)
{
long conn_id;
int rc;
int thread_slot = (int)vpArg;
/* Trap exceptions in this thread so we don't take down the whole process */
if (rc) {
"unable to open work queue, exiting");
}
NULL);
while (rc = DosReadQueue(workq, &rd, &len, (PPVOID)&worker_args, 0, DCWW_WAIT, &priority, NULLHANDLE),
sbh, bucket_alloc);
if (current_conn) {
}
SERVER_READY, NULL);
}
NULL);
}
static void server_maintenance(void *vpArg)
{
int num_idle, num_needed;
ULONG num_pending = 0;
int threadnum;
if (rc) {
"unable to open work queue in maintenance thread");
return;
}
do {
}
if (num_needed > 0) {
add_worker();
}
}
}
}
/* Signal handling routines */
{
shutdown_pending = 1;
is_graceful = 0;
}
{
shutdown_pending = 1;
is_graceful = 1;
}
static void set_signals()
{
}