#At file:///G:/bzr/mysql-5.0-bugteam/
2712 Vladislav Vaintroub 2008-11-13
Bug #20430 mysqld.exe windows service stuck in "SERVICE_STOP_PENDING" status
The problem apppear to be a race condition, when service is stopped right
after startup. We set the service status to SERVICE_RUNNING way too early
it cannot yet handle stop requests - initialization has not finished and
hEventShutdown that signals server to stop is not yet created. If somebody
issues "net stop MySQL" at this time, MySQL is not informed about the stop
and continue to run as usual, while NTService::ServiceMain() stucks forever
waiting for mysql's "main" thread to finish.
Solution is to remain in SERVICE_START_PENDING status until after server
initialization is fully complete and only then change the status to
SERVICE_RUNNING. In SERVICE_START_PENDING we do not accept service control
requests, i.e it is not possible to stop service in that time.
modified:
sql/mysqld.cc
sql/nt_servc.cc
sql/nt_servc.h
per-file messages:
sql/mysqld.cc
Set service status to running after all initialization is complete.
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2008-10-09 07:26:42 +0000
+++ b/sql/mysqld.cc 2008-11-13 15:31:08 +0000
@@ -3840,6 +3840,9 @@ we force server id to 2, but this MySQL
: mysqld_unix_port),
mysqld_port,
MYSQL_COMPILATION_COMMENT);
+#if defined(__WIN__)
+ Service.SetRunning();
+#endif
#if defined(__NT__) || defined(HAVE_SMEM)
handle_connections_methods();
=== modified file 'sql/nt_servc.cc'
--- a/sql/nt_servc.cc 2004-03-25 21:29:45 +0000
+++ b/sql/nt_servc.cc 2008-11-13 15:31:08 +0000
@@ -245,10 +245,6 @@ void NTService::ServiceMain(DWORD argc,
if (!pService->StartService())
goto error;
- // Check that the service is now running.
- if (!pService->SetStatus(SERVICE_RUNNING,NO_ERROR, 0, 0, 0))
- goto error;
-
// wait for exit event
WaitForSingleObject (pService->hExitEvent, INFINITE);
@@ -264,6 +260,14 @@ error:
return;
}
+
+void NTService::SetRunning()
+{
+ if (pService)
+ pService->SetStatus(SERVICE_RUNNING,NO_ERROR, 0, 0, 0);
+}
+
+
/* ------------------------------------------------------------------------
StartService() - starts the appliaction thread
-------------------------------------------------------------------------- */
=== modified file 'sql/nt_servc.h'
--- a/sql/nt_servc.h 2005-02-09 20:02:48 +0000
+++ b/sql/nt_servc.h 2008-11-13 15:31:08 +0000
@@ -56,7 +56,19 @@ class NTService
BOOL IsService(LPCSTR ServiceName);
BOOL got_service_option(char **argv, char *service_option);
BOOL is_super_user();
- void Stop(void); //to be called from app. to stop service
+
+ /*
+ SetRunning() is to be called by the application
+ when initialization completes and it can accept
+ stop request
+ */
+ void SetRunning(void);
+
+ /*
+ Stop() is to be called by the application to stop
+ the service
+ */
+ void Stop(void);
protected:
LPSTR ServiceName;
| Thread |
|---|
| • bzr commit into mysql-5.0-bugteam branch (vvaintroub:2712) Bug#20430 | Vladislav Vaintroub | 13 Nov |