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
fprintf(stderr, " -k uninstall | -u: uninstall an Apache service\n");
#endif
-#ifdef NETWARE
+#if defined(NETWARE)
clean_parent_exit(0);
#else
exit(1);
}
ap_destroy_mutex(start_mutex);
-
- service_set_status(SERVICE_STOPPED);
return (0);
}
#endif
|| ((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);
}
}
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);
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[] =
{
/* 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)
{
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;
memcpy(stdout, fl, sizeof(FILE));
}
- atexit(service_main_fn_terminate);
-
/* Grab it or lose it */
globdat.name = argv[0];
"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: