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

📄 mpm_winnt.c

📁 apache的软件linux版本
💻 C
📖 第 1 页 / 共 5 页
字号:
        return -1;    }    /* Create the child_exit_event */    hExitEvent = CreateEvent(NULL, TRUE, FALSE, NULL);    if (!hExitEvent) {        ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf,                     "Parent: Could not create exit event for child process");        apr_pool_destroy(ptemp);        CloseHandle(waitlist[waitlist_ready]);        return -1;    }    if (!env)     {        /* Build the env array, only once since it won't change          * for the lifetime of this parent process.         */        int envc;        for (envc = 0; _environ[envc]; ++envc) {            ;        }        env = malloc((envc + 2) * sizeof (char*));        memcpy(env, _environ, envc * sizeof (char*));        apr_snprintf(pidbuf, sizeof(pidbuf), "AP_PARENT_PID=%i", parent_pid);        env[envc] = pidbuf;        env[envc + 1] = NULL;    }    rv = apr_proc_create(&new_child, cmd, args, env, attr, ptemp);    if (rv != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,                     "Parent: Failed to create the child process.");        apr_pool_destroy(ptemp);        CloseHandle(hExitEvent);        CloseHandle(waitlist[waitlist_ready]);        CloseHandle(new_child.hproc);        return -1;    }    ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf,                 "Parent: Created child process %d", new_child.pid);    if (send_handles_to_child(ptemp, waitlist[waitlist_ready], hExitEvent,                              start_mutex, ap_scoreboard_shm,                              new_child.hproc, new_child.in)) {        /*         * This error is fatal, mop up the child and move on         * We toggle the child's exit event to cause this child          * to quit even as it is attempting to start.         */        SetEvent(hExitEvent);        apr_pool_destroy(ptemp);        CloseHandle(hExitEvent);        CloseHandle(waitlist[waitlist_ready]);        CloseHandle(new_child.hproc);        return -1;    }    /* Important:     * Give the child process a chance to run before dup'ing the sockets.     * We have already set the listening sockets noninheritable, but if      * WSADuplicateSocket runs before the child process initializes     * the listeners will be inherited anyway.     */    waitlist[waitlist_term] = new_child.hproc;    rv = WaitForMultipleObjects(2, waitlist, FALSE, INFINITE);    CloseHandle(waitlist[waitlist_ready]);    if (rv != WAIT_OBJECT_0) {        /*          * Outch... that isn't a ready signal. It's dead, Jim!         */        SetEvent(hExitEvent);        apr_pool_destroy(ptemp);        CloseHandle(hExitEvent);        CloseHandle(new_child.hproc);        return -1;    }    if (send_listeners_to_child(ptemp, new_child.pid, new_child.in)) {        /*         * This error is fatal, mop up the child and move on         * We toggle the child's exit event to cause this child          * to quit even as it is attempting to start.         */        SetEvent(hExitEvent);        apr_pool_destroy(ptemp);        CloseHandle(hExitEvent);        CloseHandle(new_child.hproc);        return -1;    }    apr_file_close(new_child.in);    *child_exit_event = hExitEvent;    *child_proc = new_child.hproc;    *child_pid = new_child.pid;    return 0;}/*********************************************************************** * master_main() * master_main() runs in the parent process.  It creates the child  * process which handles HTTP requests then waits on one of three  * events: * * restart_event * ------------- * The restart event causes master_main to start a new child process and * tells the old child process to exit (by setting the child_exit_event). * The restart event is set as a result of one of the following: * 1. An apache -k restart command on the command line * 2. A command received from Windows service manager which gets  *    translated into an ap_signal_parent(SIGNAL_PARENT_RESTART) *    call by code in service.c. * 3. The child process calling ap_signal_parent(SIGNAL_PARENT_RESTART) *    as a result of hitting MaxRequestsPerChild. * * shutdown_event  * -------------- * The shutdown event causes master_main to tell the child process to  * exit and that the server is shutting down. The shutdown event is * set as a result of one of the following: * 1. An apache -k shutdown command on the command line * 2. A command received from Windows service manager which gets *    translated into an ap_signal_parent(SIGNAL_PARENT_SHUTDOWN) *    call by code in service.c. * * child process handle * -------------------- * The child process handle will be signaled if the child process  * exits for any reason. In a normal running server, the signaling * of this event means that the child process has exited prematurely * due to a seg fault or other irrecoverable error. For server * robustness, master_main will restart the child process under this  * condtion. * * master_main uses the child_exit_event to signal the child process * to exit. **********************************************************************/#define NUM_WAIT_HANDLES 3#define CHILD_HANDLE     0#define SHUTDOWN_HANDLE  1#define RESTART_HANDLE   2static int master_main(server_rec *s, HANDLE shutdown_event, HANDLE restart_event){    int rv, cld;    int restart_pending;    int shutdown_pending;    HANDLE child_exit_event;    HANDLE event_handles[NUM_WAIT_HANDLES];    DWORD child_pid;    restart_pending = shutdown_pending = 0;    event_handles[SHUTDOWN_HANDLE] = shutdown_event;    event_handles[RESTART_HANDLE] = restart_event;    /* Create a single child process */    rv = create_process(pconf, &event_handles[CHILD_HANDLE],                         &child_exit_event, &child_pid);    if (rv < 0)     {        ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf,                     "master_main: create child process failed. Exiting.");        shutdown_pending = 1;        goto die_now;    }    if (!strcasecmp(signal_arg, "runservice")) {        mpm_service_started();    }    /* Update the scoreboard. Note that there is only a single active     * child at once.     */    ap_scoreboard_image->parent[0].quiescing = 0;    ap_scoreboard_image->parent[0].pid = child_pid;    /* Wait for shutdown or restart events or for child death */    winnt_mpm_state = AP_MPMQ_RUNNING;    rv = WaitForMultipleObjects(NUM_WAIT_HANDLES, (HANDLE *) event_handles, FALSE, INFINITE);    cld = rv - WAIT_OBJECT_0;    if (rv == WAIT_FAILED) {        /* Something serious is wrong */        ap_log_error(APLOG_MARK,APLOG_CRIT, apr_get_os_error(), ap_server_conf,                     "master_main: WaitForMultipeObjects WAIT_FAILED -- doing server shutdown");        shutdown_pending = 1;    }    else if (rv == WAIT_TIMEOUT) {        /* Hey, this cannot happen */        ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), s,                     "master_main: WaitForMultipeObjects with INFINITE wait exited with WAIT_TIMEOUT");        shutdown_pending = 1;    }    else if (cld == SHUTDOWN_HANDLE) {        /* shutdown_event signalled */        shutdown_pending = 1;        ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, s,                      "Parent: Received shutdown signal -- Shutting down the server.");        if (ResetEvent(shutdown_event) == 0) {            ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), s,                         "ResetEvent(shutdown_event)");        }    }    else if (cld == RESTART_HANDLE) {        /* Received a restart event. Prepare the restart_event to be reused          * then signal the child process to exit.          */        restart_pending = 1;        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s,                      "Parent: Received restart signal -- Restarting the server.");        if (ResetEvent(restart_event) == 0) {            ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), s,                         "Parent: ResetEvent(restart_event) failed.");        }        if (SetEvent(child_exit_event) == 0) {            ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), s,                         "Parent: SetEvent for child process %d failed.",                          event_handles[CHILD_HANDLE]);        }        /* Don't wait to verify that the child process really exits,          * just move on with the restart.         */        CloseHandle(event_handles[CHILD_HANDLE]);        event_handles[CHILD_HANDLE] = NULL;    }    else {        /* The child process exited prematurely due to a fatal error. */        DWORD exitcode;        if (!GetExitCodeProcess(event_handles[CHILD_HANDLE], &exitcode)) {            /* HUH? We did exit, didn't we? */            exitcode = APEXIT_CHILDFATAL;        }        if (   exitcode == APEXIT_CHILDFATAL             || exitcode == APEXIT_CHILDINIT            || exitcode == APEXIT_INIT) {            ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,                          "Parent: child process exited with status %u -- Aborting.", exitcode);        }        else {            int i;            restart_pending = 1;            ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf,                          "Parent: child process exited with status %u -- Restarting.", exitcode);            for (i = 0; i < ap_threads_per_child; i++) {                ap_update_child_status_from_indexes(0, i, SERVER_DEAD, NULL);            }        }        CloseHandle(event_handles[CHILD_HANDLE]);        event_handles[CHILD_HANDLE] = NULL;    }    if (restart_pending) {        ++ap_my_generation;        ap_scoreboard_image->global->running_generation = ap_my_generation;    }die_now:    if (shutdown_pending)     {        int timeout = 30000;  /* Timeout is milliseconds */        winnt_mpm_state = AP_MPMQ_STOPPING;        /* This shutdown is only marginally graceful. We will give the          * child a bit of time to exit gracefully. If the time expires,         * the child will be wacked.         */        if (!strcasecmp(signal_arg, "runservice")) {            mpm_service_stopping();        }        /* Signal the child processes to exit */        if (SetEvent(child_exit_event) == 0) {                ap_log_error(APLOG_MARK,APLOG_ERR, apr_get_os_error(), ap_server_conf,                             "Parent: SetEvent for child process %d failed", event_handles[CHILD_HANDLE]);        }        if (event_handles[CHILD_HANDLE]) {            rv = WaitForSingleObject(event_handles[CHILD_HANDLE], timeout);            if (rv == WAIT_OBJECT_0) {                ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf,                             "Parent: Child process exited successfully.");                CloseHandle(event_handles[CHILD_HANDLE]);                event_handles[CHILD_HANDLE] = NULL;            }            else {                ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf,                             "Parent: Forcing termination of child process %d ", event_handles[CHILD_HANDLE]);                TerminateProcess(event_handles[CHILD_HANDLE], 1);                CloseHandle(event_handles[CHILD_HANDLE]);                event_handles[CHILD_HANDLE] = NULL;            }        }        CloseHandle(child_exit_event);        return 0;  /* Tell the caller we do not want to restart */    }    winnt_mpm_state = AP_MPMQ_STARTING;    CloseHandle(child_exit_event);    return 1;      /* Tell the caller we want a restart */}/* service_nt_main_fn needs to append the StartService() args  * outside of our call stack and thread as the service starts... */apr_array_header_t *mpm_new_argv;/* Remember service_to_start failures to log and fail in pre_config. * Remember inst_argc and inst_argv for installing or starting the * service after we preflight the config. */AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result){    switch(query_code){        case AP_MPMQ_MAX_DAEMON_USED:            *result = MAXIMUM_WAIT_OBJECTS;            return APR_SUCCESS;        case AP_MPMQ_IS_THREADED:            *result = AP_MPMQ_STATIC;            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 = thread_limit;            return APR_SUCCESS;        case AP_MPMQ_MAX_THREADS:            *result = ap_threads_per_child;            return APR_SUCCESS;        case AP_MPMQ_MIN_SPARE_DAEMONS:            *result = 0;            return APR_SUCCESS;        case AP_MPMQ_MIN_SPARE_THREADS:                *result = 0;            return APR_SUCCESS;        case AP_MPMQ_MAX_SPARE_DAEMONS:            *result = 0;            return APR_SUCCESS;        case AP_MPMQ_MAX_SPARE_THREADS:            *result = 0;            return APR_SUCCESS;        case AP_MPMQ_MAX_REQUESTS_DAEMON:            *result = ap_max_requests_per_child;            return APR_SUCCESS;        case AP_MPMQ_MAX_DAEMONS:            *result = 0;            return APR_SUCCESS;        case AP_MPMQ_MPM_STATE:            *result = winnt_mpm_state;            return APR_SUCCESS;    }

⌨️ 快捷键说明

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