⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpm_winnt.c

📁 apache的软件linux版本
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#ifdef WIN32#define CORE_PRIVATE #include "httpd.h" #include "http_main.h" #include "http_log.h" #include "http_config.h"	/* for read_config */ #include "http_core.h"		/* for get_remote_host */ #include "http_connection.h"#include "apr_portable.h"#include "apr_thread_proc.h"#include "apr_getopt.h"#include "apr_strings.h"#include "apr_lib.h"#include "apr_shm.h"#include "apr_thread_mutex.h"#include "ap_mpm.h"#include "ap_config.h"#include "ap_listen.h"#include "mpm_default.h"#include "mpm_winnt.h"#include "mpm_common.h"#include <malloc.h>#include "apr_atomic.h"/* scoreboard.c does the heavy lifting; all we do is create the child * score by moving a handle down the pipe into the child's stdin. */extern apr_shm_t *ap_scoreboard_shm;server_rec *ap_server_conf;/* Definitions of WINNT MPM specific config globals */static HANDLE shutdown_event;	/* used to signal the parent to shutdown */static HANDLE restart_event;	/* used to signal the parent to restart */static char ap_coredump_dir[MAX_STRING_LEN];static int one_process = 0;static char const* signal_arg = NULL;OSVERSIONINFO osver; /* VER_PLATFORM_WIN32_NT */static DWORD parent_pid;DWORD my_pid;int ap_threads_per_child = 0;int use_acceptex = 1;static int thread_limit = DEFAULT_THREAD_LIMIT;static int first_thread_limit = 0;static int changed_limit_at_restart;int winnt_mpm_state = AP_MPMQ_STARTING;/* ap_my_generation are used by the scoreboard code */ap_generation_t volatile ap_my_generation=0;/* shared by service.c as global, although  * perhaps it should be private. */apr_pool_t *pconf;/* definitions from child.c */void child_main(apr_pool_t *pconf);/* used by parent to signal the child to start and exit * NOTE: these are not sophisticated enough for multiple children * so they ultimately should not be shared with child.c */extern apr_proc_mutex_t *start_mutex;extern HANDLE exit_event;  /* Only one of these, the pipe from our parent, ment only for * one child worker's consumption (not to be inherited!) * XXX: decorate this name for the trunk branch, was left simplified *      only to make the 2.2 patch trivial to read. */static HANDLE pipe;/* Stub functions until this MPM supports the connection status API */AP_DECLARE(void) ap_update_connection_status(long conn_id, const char *key, \                                             const char *value){    /* NOP */}AP_DECLARE(void) ap_reset_connection_status(long conn_id){    /* NOP */}AP_DECLARE(apr_array_header_t *) ap_get_status_table(apr_pool_t *p){    /* NOP */    return NULL;}/*  * Command processors  */static const char *set_threads_per_child (cmd_parms *cmd, void *dummy, char *arg) {    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    ap_threads_per_child = atoi(arg);    if (ap_threads_per_child > thread_limit) {        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                      "WARNING: ThreadsPerChild of %d exceeds ThreadLimit "                     "value of %d threads,", ap_threads_per_child,                      thread_limit);        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                     " lowering ThreadsPerChild to %d. To increase, please"                     " see the", thread_limit);        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                      " ThreadLimit directive.");        ap_threads_per_child = thread_limit;    }    else if (ap_threads_per_child < 1) {	ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                      "WARNING: Require ThreadsPerChild > 0, setting to 1");	ap_threads_per_child = 1;    }    return NULL;}static const char *set_thread_limit (cmd_parms *cmd, void *dummy, const char *arg) {    int tmp_thread_limit;        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    tmp_thread_limit = atoi(arg);    /* you cannot change ThreadLimit across a restart; ignore     * any such attempts     */    if (first_thread_limit &&        tmp_thread_limit != thread_limit) {        /* how do we log a message?  the error log is a bit bucket at this         * point; we'll just have to set a flag so that ap_mpm_run()         * logs a warning later         */        changed_limit_at_restart = 1;        return NULL;    }    thread_limit = tmp_thread_limit;        if (thread_limit > MAX_THREAD_LIMIT) {       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                     "WARNING: ThreadLimit of %d exceeds compile time limit "                    "of %d threads,", thread_limit, MAX_THREAD_LIMIT);       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                     " lowering ThreadLimit to %d.", MAX_THREAD_LIMIT);       thread_limit = MAX_THREAD_LIMIT;    }     else if (thread_limit < 1) {	ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                      "WARNING: Require ThreadLimit > 0, setting to 1");	thread_limit = 1;    }    return NULL;}static const char *set_disable_acceptex(cmd_parms *cmd, void *dummy, char *arg) {    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    if (use_acceptex) {        use_acceptex = 0;        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,                      "Disabled use of AcceptEx() WinSock2 API");    }    return NULL;}static const command_rec winnt_cmds[] = {LISTEN_COMMANDS,AP_INIT_TAKE1("ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF,  "Number of threads each child creates" ),AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF,  "Maximum worker threads in a server for this run of Apache"),AP_INIT_NO_ARGS("Win32DisableAcceptEx", set_disable_acceptex, NULL, RSRC_CONF,  "Disable use of the high performance AcceptEx WinSock2 API to work around buggy VPN or Firewall software"),{ NULL }};/* * Signalling Apache on NT. * * Under Unix, Apache can be told to shutdown or restart by sending various * signals (HUP, USR, TERM). On NT we don't have easy access to signals, so * we use "events" instead. The parent apache process goes into a loop * where it waits forever for a set of events. Two of those events are * called * *    apPID_shutdown *    apPID_restart * * (where PID is the PID of the apache parent process). When one of these * is signalled, the Apache parent performs the appropriate action. The events * can become signalled through internal Apache methods (e.g. if the child * finds a fatal error and needs to kill its parent), via the service * control manager (the control thread will signal the shutdown event when * requested to stop the Apache service), from the -k Apache command line, * or from any external program which finds the Apache PID from the * httpd.pid file. * * The signal_parent() function, below, is used to signal one of these events. * It can be called by any child or parent process, since it does not * rely on global variables. * * On entry, type gives the event to signal. 0 means shutdown, 1 means  * graceful restart. *//* * Initialise the signal names, in the global variables signal_name_prefix,  * signal_restart_name and signal_shutdown_name. */#define MAX_SIGNAL_NAME 30  /* Long enough for apPID_shutdown, where PID is an int */char signal_name_prefix[MAX_SIGNAL_NAME];char signal_restart_name[MAX_SIGNAL_NAME]; char signal_shutdown_name[MAX_SIGNAL_NAME];void setup_signal_names(char *prefix){    apr_snprintf(signal_name_prefix, sizeof(signal_name_prefix), prefix);        apr_snprintf(signal_shutdown_name, sizeof(signal_shutdown_name), 	"%s_shutdown", signal_name_prefix);        apr_snprintf(signal_restart_name, sizeof(signal_restart_name), 	"%s_restart", signal_name_prefix);    }int volatile is_graceful = 0;AP_DECLARE(int) ap_graceful_stop_signalled(void){    return is_graceful;}AP_DECLARE(void) ap_signal_parent(ap_signal_parent_e type){    HANDLE e;    char *signal_name;        if (parent_pid == my_pid) {        switch(type) {           case SIGNAL_PARENT_SHUTDOWN:            {               SetEvent(shutdown_event);                break;           }           /* This MPM supports only graceful restarts right now */           case SIGNAL_PARENT_RESTART:            case SIGNAL_PARENT_RESTART_GRACEFUL:           {               is_graceful = 1;               SetEvent(restart_event);                break;           }        }	return;    }    switch(type) {       case SIGNAL_PARENT_SHUTDOWN:        {           signal_name = signal_shutdown_name;            break;       }       /* This MPM supports only graceful restarts right now */       case SIGNAL_PARENT_RESTART:        case SIGNAL_PARENT_RESTART_GRACEFUL:       {           signal_name = signal_restart_name;                is_graceful = 1;           break;       }       default:            return;    }    e = OpenEvent(EVENT_MODIFY_STATE, FALSE, signal_name);    if (!e) {	/* Um, problem, can't signal the parent, which means we can't	 * signal ourselves to die. Ignore for now...	 */	ap_log_error(APLOG_MARK, APLOG_EMERG, apr_get_os_error(), ap_server_conf,                     "OpenEvent on %s event", signal_name);	return;    }    if (SetEvent(e) == 0) {	/* Same problem as above */	ap_log_error(APLOG_MARK, APLOG_EMERG, apr_get_os_error(), ap_server_conf,                     "SetEvent on %s event", signal_name);	CloseHandle(e);	return;    }    CloseHandle(e);}/* * Passed the following handles [in sync with send_handles_to_child()] * *   ready event [signal the parent immediately, then close] *   exit event  [save to poll later] *   start mutex [signal from the parent to begin accept()] *   scoreboard shm handle [to recreate the ap_scoreboard] */void get_handles_from_parent(server_rec *s, HANDLE *child_exit_event,                             apr_proc_mutex_t **child_start_mutex,                             apr_shm_t **scoreboard_shm){    HANDLE hScore;    HANDLE ready_event;    HANDLE os_start;    DWORD BytesRead;    void *sb_shared;    apr_status_t rv;        /* *** We now do this was back in winnt_rewrite_args     * pipe = GetStdHandle(STD_INPUT_HANDLE);     */    if (!ReadFile(pipe, &ready_event, sizeof(HANDLE),                  &BytesRead, (LPOVERLAPPED) NULL)        || (BytesRead != sizeof(HANDLE))) {        ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf,                     "Child %d: Unable to retrieve the ready event from the parent", my_pid);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -