📄 mpmt_os2.c
字号:
PID child_pid; int active_children = 0; /* Count number of active children */ for (slot=0; slot < HARD_SERVER_LIMIT; slot++) { active_children += ap_scoreboard_image->parent[slot].pid != 0 && !ap_scoreboard_image->parent[slot].quiescing; } /* Spawn children if needed */ for (slot=0; slot < HARD_SERVER_LIMIT && active_children < ap_daemons_to_start; slot++) { if (ap_scoreboard_image->parent[slot].pid == 0) { spawn_child(slot); active_children++; } } rc = DosWaitChild(DCWA_PROCESSTREE, DCWW_NOWAIT, &proc_rc, &child_pid, 0); if (rc == 0) { /* A child has terminated, remove its scoreboard entry & terminate if necessary */ for (slot=0; ap_scoreboard_image->parent[slot].pid != child_pid && slot < HARD_SERVER_LIMIT; slot++); if (slot < HARD_SERVER_LIMIT) { ap_scoreboard_image->parent[slot].pid = 0; ap_scoreboard_image->parent[slot].quiescing = 0; if (proc_rc.codeTerminate == TC_EXIT) { /* Child terminated normally, check its exit code and * terminate server if child indicates a fatal error */ if (proc_rc.codeResult == APEXIT_CHILDFATAL) break; } } } else if (rc == ERROR_CHILD_NOT_COMPLETE) { /* No child exited, lets sleep for a while.... */ apr_sleep(SCOREBOARD_MAINTENANCE_INTERVAL); } } /* Signal children to shut down, either gracefully or immediately */ for (slot=0; slot<HARD_SERVER_LIMIT; slot++) { kill(ap_scoreboard_image->parent[slot].pid, is_graceful ? SIGHUP : SIGTERM); } DosFreeMem(parent_info); return restart_pending;}static void spawn_child(int slot){ PPIB ppib; PTIB ptib; char fail_module[100]; char progname[CCHMAXPATH]; RESULTCODES proc_rc; ULONG rc; ap_scoreboard_image->parent[slot].generation = ap_my_generation; DosGetInfoBlocks(&ptib, &ppib); DosQueryModuleName(ppib->pib_hmte, sizeof(progname), progname); rc = DosExecPgm(fail_module, sizeof(fail_module), EXEC_ASYNCRESULT, ppib->pib_pchcmd, NULL, &proc_rc, progname); if (rc) { ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, "error spawning child, slot %d", slot); } if (ap_max_daemons_limit < slot) { ap_max_daemons_limit = slot; } ap_scoreboard_image->parent[slot].pid = proc_rc.codeTerminate;}/* Signal handling routines */static void sig_term(int sig){ shutdown_pending = 1; signal(SIGTERM, SIG_DFL);}static void sig_restart(int sig){ if (sig == SIGUSR1) { is_graceful = 1; } restart_pending = 1;}static void set_signals(){ struct sigaction sa; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = sig_term; if (sigaction(SIGTERM, &sa, NULL) < 0) ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGTERM)"); if (sigaction(SIGINT, &sa, NULL) < 0) ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGINT)"); sa.sa_handler = sig_restart; if (sigaction(SIGHUP, &sa, NULL) < 0) ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGHUP)"); if (sigaction(SIGUSR1, &sa, NULL) < 0) ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGUSR1)");}/* Enquiry functions used get MPM status info */AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result){ switch (query_code) { case AP_MPMQ_MAX_DAEMON_USED: *result = ap_max_daemons_limit; return APR_SUCCESS; case AP_MPMQ_IS_THREADED: *result = AP_MPMQ_DYNAMIC; return APR_SUCCESS; case AP_MPMQ_IS_FORKED: *result = AP_MPMQ_NOT_SUPPORTED; return APR_SUCCESS; case AP_MPMQ_HARD_LIMIT_DAEMONS: *result = HARD_SERVER_LIMIT; return APR_SUCCESS; case AP_MPMQ_HARD_LIMIT_THREADS: *result = HARD_THREAD_LIMIT; return APR_SUCCESS; case AP_MPMQ_MIN_SPARE_DAEMONS: *result = 0; return APR_SUCCESS; case AP_MPMQ_MAX_SPARE_DAEMONS: *result = 0; return APR_SUCCESS; case AP_MPMQ_MAX_REQUESTS_DAEMON: *result = ap_max_requests_per_child; return APR_SUCCESS; } return APR_ENOTIMPL;} int ap_graceful_stop_signalled(void){ return is_graceful;}/* Configuration handling stuff */static int mpmt_os2_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp){ one_process = ap_exists_config_define("ONE_PROCESS") || ap_exists_config_define("DEBUG"); is_graceful = 0; ap_listen_pre_config(); ap_daemons_to_start = DEFAULT_START_DAEMON; ap_thread_limit = HARD_THREAD_LIMIT; ap_pid_fname = DEFAULT_PIDLOG; ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; ap_extended_status = 0; ap_min_spare_threads = DEFAULT_MIN_SPARE_THREAD; ap_max_spare_threads = DEFAULT_MAX_SPARE_THREAD;#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED;#endif return OK;}static void mpmt_os2_hooks(apr_pool_t *p){ ap_hook_pre_config(mpmt_os2_pre_config, NULL, NULL, APR_HOOK_MIDDLE);}static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, const char *arg){ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); if (err != NULL) { return err; } ap_daemons_to_start = atoi(arg); return NULL;}static const char *set_min_spare_threads(cmd_parms *cmd, void *dummy, const char *arg){ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); if (err != NULL) { return err; } ap_min_spare_threads = atoi(arg); if (ap_min_spare_threads <= 0) { ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "WARNING: detected MinSpareThreads set to non-positive."); ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "Resetting to 1 to avoid almost certain Apache failure."); ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "Please read the documentation."); ap_min_spare_threads = 1; } return NULL;}static const char *set_max_spare_threads(cmd_parms *cmd, void *dummy, const char *arg){ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); if (err != NULL) { return err; } ap_max_spare_threads = atoi(arg); return NULL;}static const char *ignore_cmd(cmd_parms *cmd, void *dummy, const char *arg){ return NULL;}static const command_rec mpmt_os2_cmds[] = {LISTEN_COMMANDS,AP_INIT_TAKE1( "StartServers", set_daemons_to_start, NULL, RSRC_CONF, "Number of child processes launched at server startup" ),AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF, "Minimum number of idle children, to handle request spikes"),AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF, "Maximum number of idle children"),AP_INIT_TAKE1("User", ignore_cmd, NULL, RSRC_CONF, "Not applicable on this platform"),AP_INIT_TAKE1("Group", ignore_cmd, NULL, RSRC_CONF, "Not applicable on this platform"),AP_INIT_TAKE1("ScoreBoardFile", ignore_cmd, NULL, RSRC_CONF, \ "Not applicable on this platform"),{ NULL }};module AP_MODULE_DECLARE_DATA mpm_mpmt_os2_module = { MPM20_MODULE_STUFF, NULL, /* hook to run before apache parses args */ NULL, /* create per-directory config structure */ NULL, /* merge per-directory config structures */ NULL, /* create per-server config structure */ NULL, /* merge per-server config structures */ mpmt_os2_cmds, /* command apr_table_t */ mpmt_os2_hooks, /* register_hooks */};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -