Jeff Trawick wrote:
Bill Stoddard wrote:

Do you know of any cases that actually require mpm_state to be updated in ap_signal_parent()? Setting winnt_mpm_state to AP_MPMQ_STOPPING in child main should be sufficient unless I am missing something.


the code in service.c which shuts down the server for other reasons?

AFAICT, not all code in child main that leads to termination will call ap_signal_parent(), and not all calls to ap_signal_parent() come through child_main

but... where will module code be called (pool cleanups, other child maintenance routines)? the desire here is for any such code to see AP_MPMQ_STOPPING... based on this, maybe it can be set in fewer places or some common place

(btw, thanks for having a look at this!)


Humm.... no simple answers. Thinking out loud.


All code that runs in the child process will enter/exit via child main which is called on the ap_mpm_run hook. So setting state to STARTING at process initialization time is good. Setting state to RUNNING then STOPPING in child_main is good. This covers all cases in the child process. So child processes do not require the changes to ap_signal_parent(). Agree?

The module architecture is still a bit crufty on Windows because the parent process also calls all the module init/cleanup hooks (becase Windows does not support Unix fork() semantics). Most modules should simply get out of the way if they detect they are being called in the parent process (and not being run in ONE_PROCESS mode) but there can be exceptions. Modules may need to maintain shared resources (e.g. shared memory segment) across graceful restarts. Or someday when we enable multiple active child processes, modules may need to share state between child processes.

Checkout this patch. I -know- state AP_MPMQ_RESTARTING does not exist in ap_mpm.h (so this patch will not compile) but consider it for purposes of discussion. The parent process always goes through master_main() and master_main() can distinguish between stopping and graceful restarting and this would be useful information for a Windows module in the parent process for purposes discussed above.

Index: mpm_winnt.c
===================================================================
RCS file: /home/cvs/httpd-2.0/server/mpm/winnt/mpm_winnt.c,v
retrieving revision 1.305
diff -u -r1.305 mpm_winnt.c
--- mpm_winnt.c 9 Jan 2004 20:41:06 -0000       1.305
+++ mpm_winnt.c 14 Jan 2004 14:18:44 -0000
@@ -307,7 +307,6 @@
         switch(type) {
            case SIGNAL_PARENT_SHUTDOWN:
            {
-               winnt_mpm_state = AP_MPMQ_STOPPING;
                SetEvent(shutdown_event);
                break;
            }
@@ -315,7 +314,6 @@
            case SIGNAL_PARENT_RESTART:
            case SIGNAL_PARENT_RESTART_GRACEFUL:
            {
-               winnt_mpm_state = AP_MPMQ_STOPPING;
                is_graceful = 1;
                SetEvent(restart_event);
                break;
@@ -327,7 +325,6 @@
     switch(type) {
        case SIGNAL_PARENT_SHUTDOWN:
        {
-           winnt_mpm_state = AP_MPMQ_STOPPING;
            signal_name = signal_shutdown_name;
            break;
        }
@@ -335,7 +332,6 @@
        case SIGNAL_PARENT_RESTART:
        case SIGNAL_PARENT_RESTART_GRACEFUL:
        {
-           winnt_mpm_state = AP_MPMQ_STOPPING;
            signal_name = signal_restart_name;
            is_graceful = 1;
            break;
@@ -934,6 +930,7 @@
     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) {
@@ -1013,6 +1010,7 @@
     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,
@@ -1044,7 +1042,7 @@
         }
         return 0;  /* Tell the caller we do not want to restart */
     }
-
+    winnt_mpm_state = AP_MPMQ_RESTARTING;
     return 1;      /* Tell the caller we want a restart */
 }







Reply via email to