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

📄 prefork.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 4 页
字号:
                    "caught SIGTERM, shutting down");        return 1;    } else if (shutdown_pending) {        /* Time to perform a graceful shut down:         * Reap the inactive children, and ask the active ones         * to close their listeners, then wait until they are         * all done to exit.         */        int active_children;        apr_time_t cutoff = 0;        /* Stop listening */        ap_close_listeners();        /* kill off the idle ones */        ap_mpm_pod_killpg(pod, ap_max_daemons_limit);        /* Send SIGUSR1 to the active children */        active_children = 0;        for (index = 0; index < ap_daemons_limit; ++index) {            if (ap_scoreboard_image->servers[index][0].status != SERVER_DEAD) {                /* Ask each child to close its listeners. */                ap_mpm_safe_kill(MPM_CHILD_PID(index), AP_SIG_GRACEFUL);                active_children++;            }        }        /* Allow each child which actually finished to exit */        ap_relieve_child_processes();        /* cleanup pid file */        {            const char *pidfile = NULL;            pidfile = ap_server_root_relative (pconf, ap_pid_fname);            if ( pidfile != NULL && unlink(pidfile) == 0)                ap_log_error(APLOG_MARK, APLOG_INFO,                                0, ap_server_conf,                                "removed PID file %s (pid=%ld)",                                pidfile, (long)getpid());        }        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,           "caught " AP_SIG_GRACEFUL_STOP_STRING ", shutting down gracefully");        if (ap_graceful_shutdown_timeout) {            cutoff = apr_time_now() +                     apr_time_from_sec(ap_graceful_shutdown_timeout);        }        /* Don't really exit until each child has finished */        shutdown_pending = 0;        do {            /* Pause for a second */            sleep(1);            /* Relieve any children which have now exited */            ap_relieve_child_processes();            active_children = 0;            for (index = 0; index < ap_daemons_limit; ++index) {                if (ap_mpm_safe_kill(MPM_CHILD_PID(index), 0) == APR_SUCCESS) {                    active_children = 1;                    /* Having just one child is enough to stay around */                    break;                }            }        } while (!shutdown_pending && active_children &&                 (!ap_graceful_shutdown_timeout || apr_time_now() < cutoff));        /* We might be here because we received SIGTERM, either         * way, try and make sure that all of our processes are         * really dead.         */        unixd_killpg(getpgrp(), SIGTERM);        return 1;    }    /* we've been told to restart */    apr_signal(SIGHUP, SIG_IGN);    apr_signal(AP_SIG_GRACEFUL, SIG_IGN);    if (one_process) {        /* not worth thinking about */        return 1;    }    /* advance to the next generation */    /* XXX: we really need to make sure this new generation number isn't in     * use by any of the children.     */    ++ap_my_generation;    ap_scoreboard_image->global->running_generation = ap_my_generation;    if (is_graceful) {        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,                    "Graceful restart requested, doing restart");        /* kill off the idle ones */        ap_mpm_pod_killpg(pod, ap_max_daemons_limit);        /* This is mostly for debugging... so that we know what is still         * gracefully dealing with existing request.  This will break         * in a very nasty way if we ever have the scoreboard totally         * file-based (no shared memory)         */        for (index = 0; index < ap_daemons_limit; ++index) {            if (ap_scoreboard_image->servers[index][0].status != SERVER_DEAD) {                ap_scoreboard_image->servers[index][0].status = SERVER_GRACEFUL;                /* Ask each child to close its listeners.                 *                 * NOTE: we use the scoreboard, because if we send SIGUSR1                 * to every process in the group, this may include CGI's,                 * piped loggers, etc. They almost certainly won't handle                 * it gracefully.                 */                ap_mpm_safe_kill(ap_scoreboard_image->parent[index].pid, AP_SIG_GRACEFUL);            }        }    }    else {        /* Kill 'em off */        if (unixd_killpg(getpgrp(), SIGHUP) < 0) {            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGHUP");        }        ap_reclaim_child_processes(0);          /* Not when just starting up */        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,                    "SIGHUP received.  Attempting to restart");    }    return 0;}/* This really should be a post_config hook, but the error log is already * redirected by that point, so we need to do this in the open_logs phase. */static int prefork_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s){    apr_status_t rv;    pconf = p;    ap_server_conf = s;    if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) {        ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0,                     NULL, "no listening sockets available, shutting down");        return DONE;    }    if ((rv = ap_mpm_pod_open(pconf, &pod))) {        ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_STARTUP, rv, NULL,                "Could not open pipe-of-death.");        return DONE;    }    return OK;}static int prefork_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp){    static int restart_num = 0;    int no_detach, debug, foreground;    apr_status_t rv;    mpm_state = AP_MPMQ_STARTING;    debug = ap_exists_config_define("DEBUG");    if (debug) {        foreground = one_process = 1;        no_detach = 0;    }    else    {        no_detach = ap_exists_config_define("NO_DETACH");        one_process = ap_exists_config_define("ONE_PROCESS");        foreground = ap_exists_config_define("FOREGROUND");    }    /* sigh, want this only the second time around */    if (restart_num++ == 1) {        is_graceful = 0;        if (!one_process && !foreground) {            rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND                                           : APR_PROC_DETACH_DAEMONIZE);            if (rv != APR_SUCCESS) {                ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL,                             "apr_proc_detach failed");                return HTTP_INTERNAL_SERVER_ERROR;            }        }        parent_pid = ap_my_pid = getpid();    }    unixd_pre_config(ptemp);    ap_listen_pre_config();    ap_daemons_to_start = DEFAULT_START_DAEMON;    ap_daemons_min_free = DEFAULT_MIN_FREE_DAEMON;    ap_daemons_max_free = DEFAULT_MAX_FREE_DAEMON;    ap_daemons_limit = server_limit;    ap_pid_fname = DEFAULT_PIDLOG;    ap_lock_fname = DEFAULT_LOCKFILE;    ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;    ap_extended_status = 0;#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE    ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED;#endif    apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir));    return OK;}static void prefork_hooks(apr_pool_t *p){    /* The prefork open_logs phase must run before the core's, or stderr     * will be redirected to a file, and the messages won't print to the     * console.     */    static const char *const aszSucc[] = {"core.c", NULL};#ifdef AUX3    (void) set42sig();#endif    ap_hook_open_logs(prefork_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE);    /* we need to set the MPM state before other pre-config hooks use MPM query     * to retrieve it, so register as REALLY_FIRST     */    ap_hook_pre_config(prefork_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);}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_free_servers(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_min_free = atoi(arg);    if (ap_daemons_min_free <= 0) {       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                    "WARNING: detected MinSpareServers 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_daemons_min_free = 1;    }    return NULL;}static const char *set_max_free_servers(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_max_free = atoi(arg);    return NULL;}static const char *set_max_clients (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_limit = atoi(arg);    if (ap_daemons_limit > server_limit) {       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                    "WARNING: MaxClients of %d exceeds ServerLimit value "                    "of %d servers,", ap_daemons_limit, server_limit);       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                    " lowering MaxClients to %d.  To increase, please "                    "see the ServerLimit", server_limit);       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                    " directive.");       ap_daemons_limit = server_limit;    }    else if (ap_daemons_limit < 1) {        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                     "WARNING: Require MaxClients > 0, setting to 1");        ap_daemons_limit = 1;    }    return NULL;}static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg){    int tmp_server_limit;    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    tmp_server_limit = atoi(arg);    /* you cannot change ServerLimit across a restart; ignore     * any such attempts     */    if (first_server_limit &&        tmp_server_limit != server_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;    }    server_limit = tmp_server_limit;    if (server_limit > MAX_SERVER_LIMIT) {       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                    "WARNING: ServerLimit of %d exceeds compile time limit "                    "of %d servers,", server_limit, MAX_SERVER_LIMIT);       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                    " lowering ServerLimit to %d.", MAX_SERVER_LIMIT);       server_limit = MAX_SERVER_LIMIT;    }    else if (server_limit < 1) {        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                     "WARNING: Require ServerLimit > 0, setting to 1");        server_limit = 1;    }    return NULL;}static const command_rec prefork_cmds[] = {UNIX_DAEMON_COMMANDS,LISTEN_COMMANDS,AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF,              "Number of child processes launched at server startup"),AP_INIT_TAKE1("MinSpareServers", set_min_free_servers, NULL, RSRC_CONF,              "Minimum number of idle children, to handle request spikes"),AP_INIT_TAKE1("MaxSpareServers", set_max_free_servers, NULL, RSRC_CONF,              "Maximum number of idle children"),AP_INIT_TAKE1("MaxClients", set_max_clients, NULL, RSRC_CONF,              "Maximum number of children alive at the same time"),AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF,              "Maximum value of MaxClients for this run of Apache"),AP_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND,{ NULL }};module AP_MODULE_DECLARE_DATA mpm_prefork_module = {    MPM20_MODULE_STUFF,    ap_mpm_rewrite_args,        /* 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 */    prefork_cmds,               /* command apr_table_t */    prefork_hooks,              /* register hooks */};

⌨️ 快捷键说明

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