mpm_netware.c revision 6de8046f8f7e07cd83895a528df25d977e502c76
af687ddbab64fce492e06d194acd60da69b59608nd/* Copyright 2001-2004 The Apache Software Foundation
af687ddbab64fce492e06d194acd60da69b59608nd * Licensed under the Apache License, Version 2.0 (the "License");
af687ddbab64fce492e06d194acd60da69b59608nd * you may not use this file except in compliance with the License.
af687ddbab64fce492e06d194acd60da69b59608nd * You may obtain a copy of the License at
af687ddbab64fce492e06d194acd60da69b59608nd * Unless required by applicable law or agreed to in writing, software
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * distributed under the License is distributed on an "AS IS" BASIS,
af687ddbab64fce492e06d194acd60da69b59608nd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
af687ddbab64fce492e06d194acd60da69b59608nd * See the License for the specific language governing permissions and
af687ddbab64fce492e06d194acd60da69b59608nd * limitations under the License.
af687ddbab64fce492e06d194acd60da69b59608nd * httpd.c: simple http daemon for answering WWW file requests
af687ddbab64fce492e06d194acd60da69b59608nd * 03-21-93 Rob McCool wrote original code (up to NCSA HTTPd 1.3)
fe641696aaf4dcf7576af684eeb47c5fa8cc87f5jorton * 03-06-95 blong
af687ddbab64fce492e06d194acd60da69b59608nd * changed server number for child-alone processes to 0 and changed name
7023b60a6c3a85c1d208fbee730f919e61351ac6nd * of processes
7023b60a6c3a85c1d208fbee730f919e61351ac6nd * 03-10-95 blong
af687ddbab64fce492e06d194acd60da69b59608nd * Added numerous speed hacks proposed by Robert S. Thau (rst@ai.mit.edu)
4249c36b4ab4024464db91e2606f651f3b20c1e5nd * including set group before fork, and call gettime before to fork
af687ddbab64fce492e06d194acd60da69b59608nd * to set up libraries.
4249c36b4ab4024464db91e2606f651f3b20c1e5nd * 04-14-95 rst / rh
af687ddbab64fce492e06d194acd60da69b59608nd * Brandon's code snarfed from NCSA 1.4, but tinkered to work with the
af687ddbab64fce492e06d194acd60da69b59608nd * Apache server, and also to have child processes do accept() directly.
af687ddbab64fce492e06d194acd60da69b59608nd * April-July '95 rst
af687ddbab64fce492e06d194acd60da69b59608nd * Extensive rework for Apache.
#define APR_WANT_STRFUNC
#include "apr_want.h"
#include <unistd.h>
#define CORE_PRIVATE
#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_connection.h"
#include "scoreboard.h"
#include "ap_mpm.h"
#include "mpm_common.h"
#include "ap_listen.h"
#include "ap_mmn.h"
#ifdef HAVE_TIME_H
#include <time.h>
#include <signal.h>
#include <netware.h>
#include <library.h>
#include <screen.h>
#ifndef HARD_SERVER_LIMIT
static int ap_threads_to_start=0;
static int ap_threads_min_free=0;
static int ap_threads_max_free=0;
static int ap_threads_limit=0;
static int listenmaxfd;
static int die_now = 0;
static unsigned long worker_thread_count;
static int request_count;
/* Structure used to register/deregister a console handler with the OS */
static int InstallConsoleHandler(void);
static void RemoveConsoleHandler(void);
#define HANDLEDCOMMAND 0
static int show_settings = 0;
#ifdef DBPRINT_ON
#define DBPRINT0(s)
static int volatile shutdown_pending;
static int volatile restart_pending;
static int volatile is_graceful;
if (!shutdown_pending) {
if (worker_num >=0)
switch(query_code){
case AP_MPMQ_MAX_DAEMON_USED:
return APR_SUCCESS;
case AP_MPMQ_IS_THREADED:
return APR_SUCCESS;
case AP_MPMQ_IS_FORKED:
return APR_SUCCESS;
return APR_SUCCESS;
return APR_SUCCESS;
case AP_MPMQ_MAX_THREADS:
return APR_SUCCESS;
*result = 0;
return APR_SUCCESS;
return APR_SUCCESS;
*result = 0;
return APR_SUCCESS;
return APR_SUCCESS;
return APR_SUCCESS;
case AP_MPMQ_MAX_DAEMONS:
return APR_SUCCESS;
case AP_MPMQ_MPM_STATE:
return APR_SUCCESS;
return APR_ENOTIMPL;
static void mpm_term(void)
wait_to_finish = 0;
while (wait_to_finish) {
static void restart(void)
static void set_signals(void)
if (wait) {
while (wait_to_finish) {
int ap_graceful_stop_signalled(void)
#ifdef DBINFO_ON
static int would_block = 0;
static int retry_success = 0;
static int retry_fail = 0;
static int avg_retries = 0;
int requests_this_child = 0;
int sockdes;
int srv;
int wouldblock_retry;
while (!die_now) {
if ((ap_max_requests_per_child > 0
if (shutdown_pending || restart_pending || (ap_scoreboard_image->servers[0][my_worker_num].status == WORKER_IDLE_KILL)) {
if (srv <= 0) {
if (srv < 0) {
if (!lr)
goto got_listener;
if (!lr)
while (wouldblock_retry) {
if (wouldblock_retry--) {
#ifdef DBINFO_ON
#ifdef DBINFO_ON
would_block++;
retry_fail++;
if (current_conn) {
int tid;
int err=0;
if (ctx = NXContextAlloc((void (*)(void *)) worker_main, (void*)slot, NX_PRIO_MED, ap_thread_stack_size, NX_CTX_NORMAL, &err)) {
if (err) {
if (err) {
#ifndef MAX_SPAWN_RATE
static int hold_off_on_exponential_spawning;
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_threads_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) {
static void display_settings ()
#ifdef DBINFO_ON
would_block = 0;
request_count = 0;
for (i=0;i<SERVER_NUM_STATUS;i++) {
status_array[i] = 0;
for (i = 0; i < ap_threads_limit; ++i) {
for (i=0;i<SERVER_NUM_STATUS;i++) {
case SERVER_DEAD:
case SERVER_STARTING:
case SERVER_READY:
case SERVER_BUSY_READ:
case SERVER_BUSY_WRITE:
case SERVER_BUSY_KEEPALIVE:
case SERVER_BUSY_LOG:
case SERVER_BUSY_DNS:
case SERVER_CLOSING:
case SERVER_GRACEFUL:
case SERVER_IDLE_KILL:
if (i != SERVER_DEAD)
#ifdef DBINFO_ON
static void show_server_data()
module **m;
int sockdes;
static int shutdown_listeners()
ap_server_conf = s;
if (setup_listeners(s)) {
worker_thread_count = 0;
if (!is_graceful) {
set_signals();
request_count = 0;
if (hold_screen_on_exit > 0) {
hold_screen_on_exit = 0;
if (show_settings)
while (worker_thread_count > 0) {
while (worker_thread_count > 0) {
int debug;
is_graceful = 0;
if (addrname) {
ap_extended_status = 0;
#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE
return OK;
char *def_server_root;
const char *opt_arg;
for (i=len; i; i--) {
s[i] = NULL;
if (opt_arg) {
if (opt_arg) {
char *pID;
return NOTMYCOMMAND;
return NOTMYCOMMAND;
return NOTMYCOMMAND;
if (pID) {
pID++;
return NOTMYCOMMAND;
restart();
if (show_settings) {
show_settings = 0;
show_settings = 0;
return HANDLEDCOMMAND;
return NOTMYCOMMAND;
static int InstallConsoleHandler(void)
static void RemoveConsoleHandler(void)
return err;
return NULL;
return err;
if (ap_threads_min_free <= 0) {
return NULL;
return err;
return NULL;
return err;
return NULL;
const char *arg)
return err;
return NULL;
{ NULL }