]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Solved a very serious threading problem with WinNT/2K Services. The
authorWilliam A. Rowe Jr <wrowe@apache.org>
Mon, 26 Mar 2001 19:25:54 +0000 (19:25 +0000)
committerWilliam A. Rowe Jr <wrowe@apache.org>
Mon, 26 Mar 2001 19:25:54 +0000 (19:25 +0000)
  moment master_main told that the shutdown was complete, the parent
  control thread exited Apache, leaving mod_jserv's Java process running
  and alternately invoking mod_perl's cleanups from the correct thread
  or the service control thread. [William Rowe]

  List of PR's too long to cite...

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x@88590 13f79535-47bb-0310-9956-ffa450edef68

src/CHANGES
src/main/http_main.c
src/os/win32/service.c

index 6141e6835fcb2276a22a0d6e47838f1766bc78c1..9248e2a1a7b47f02e91b2344f524f813b23131b2 100644 (file)
@@ -1,5 +1,11 @@
 Changes with Apache 1.3.20
 
+  *) Solved a very serious threading problem with WinNT/2K Services.  The
+     moment master_main told that the shutdown was complete, the parent
+     control thread exited Apache, leaving mod_jserv's Java process running
+     and alternately invoking mod_perl's cleanups from the correct thread
+     or the service control thread. [William Rowe]
+
   *) Populate the Win32 HKLM\System\CurrentControlSet\Services\[apachesvc]
      key with the Description value of the running server across all Win32
      platforms, including NT, ME and 9x.  This value is the server_version
index a3f66bafc9c0ff511a3424d642f31ad441f7f43d..cb3fc6bb7cfbea65e9b49c6b32e1300a57ef72d2 100644 (file)
@@ -1088,7 +1088,7 @@ static void usage(char *bin)
     fprintf(stderr, "  -k uninstall | -u: uninstall an Apache service\n");
 #endif
 
-#ifdef NETWARE
+#if defined(NETWARE)
     clean_parent_exit(0);
 #else
     exit(1);
@@ -6568,8 +6568,6 @@ die_now:
     }
 
     ap_destroy_mutex(start_mutex);
-
-    service_set_status(SERVICE_STOPPED);
     return (0);
 }
 #endif
@@ -6686,7 +6684,11 @@ int REALMAIN(int argc, char *argv[])
             || ((argc == 2) && !strcmp(argv[1], "--ntservice")))
         {
             service_main(apache_main, argc, argv);
-            clean_parent_exit(0);
+            /* this was the end of the service control thread... 
+             * cleanups already ran when second thread of apache_main
+             * terminated, so simply...
+             */
+            exit(0);
         }
     }
 
index 65df60d3d683a27da08689e0871f0d478484ae70..33cdac10be8a053a7465806e77e8f66be891615b 100644 (file)
@@ -127,7 +127,21 @@ void hold_console_open_on_error(void)
     CONSOLE_SCREEN_BUFFER_INFO coninfo;
     INPUT_RECORD in;
     char count[16];
-    
+
+#ifdef WIN32
+    /* The service parent cannot just 'pop' out of the main thread,
+     * as it is about to try to do...
+     * We must end this thread properly so the service control
+     * thread exits gracefully.  atexit()s registered in the running
+     * apache_main thread _should_ have already been handled, so now
+     * we can exit this thread and allow the service thread to exit.
+     */
+    if (isWindowsNT() && isProcessService() && globdat.connected) {
+        service_set_status(SERVICE_STOPPED);
+        ExitThread(0);
+    }
+#endif
+
     if (!real_exit_code)
         return;
     hConIn = GetStdHandle(STD_INPUT_HANDLE);
@@ -411,6 +425,9 @@ int service95_main(int (*main_fn)(int, char **), int argc, char **argv,
     return (globdat.exit_status);
 }
 
+static HANDLE eventlog_pipewrite = NULL;
+static HANDLE eventlog_thread = NULL;
+
 int service_main(int (*main_fn)(int, char **), int argc, char **argv )
 {
     SERVICE_TABLE_ENTRY dispatchTable[] =
@@ -435,17 +452,20 @@ int service_main(int (*main_fn)(int, char **), int argc, char **argv )
     {
         /* This is a genuine failure of the SCM. */
         ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
-        "Error starting service control dispatcher");
-        return(globdat.exit_status);
+                     "Error starting service control dispatcher");
     }
-    else
+
+    globdat.connected = 0;
+
+    if (eventlog_pipewrite)
     {
-        return(globdat.exit_status);
+        CloseHandle(eventlog_pipewrite);
+        WaitForSingleObject(eventlog_thread, 10000);
+        eventlog_pipewrite = NULL;
     }
-}
 
-static HANDLE eventlog_pipewrite = NULL;
-static HANDLE eventlog_thread = NULL;
+    return(globdat.exit_status);
+}
 
 long __stdcall service_stderr_thread(LPVOID hPipe)
 {
@@ -523,22 +543,6 @@ long __stdcall service_stderr_thread(LPVOID hPipe)
     return 0;
 }
 
-static void service_main_fn_terminate(void)
-{
-    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL,
-                 "The service manager thread is terminating.");
-
-    if (eventlog_pipewrite)
-    {
-        CloseHandle(eventlog_pipewrite);
-        WaitForSingleObject(eventlog_thread, 10000);
-        eventlog_pipewrite = NULL;
-        eventlog_pipewrite = NULL;
-    }
-
-    ReportStatusToSCMgr(SERVICE_STOPPED, NO_ERROR, 0);
-}
-
 void __stdcall service_main_fn(DWORD argc, LPTSTR *argv)
 {
     HANDLE hCurrentProcess;
@@ -641,8 +645,6 @@ void __stdcall service_main_fn(DWORD argc, LPTSTR *argv)
         memcpy(stdout, fl, sizeof(FILE));
     }
 
-    atexit(service_main_fn_terminate);
-
     /* Grab it or lose it */
     globdat.name = argv[0];
 
@@ -781,7 +783,6 @@ VOID WINAPI service_ctrl(DWORD dwCtrlCode)
                          "Service Stop/Shutdown signaled, shutting down server.");
             ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 15000);
             ap_start_shutdown();
-            // ReportStatusToSCMgr(SERVICE_STOPPED, NO_ERROR, 0);
             break;
 
         case SERVICE_APACHE_RESTART: