mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
f2a610e1e0
status The problem appears to be a race condition, when service is being 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 continues 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. sql/mysqld.cc: Set service status to running after all initialization is complete sql/nt_servc.cc: New method SetRunning() to be called by application to set service status to SERVICE_RUNNING when apllication has finished initialization. sql/nt_servc.h: New method SetRunning() to be called by application when initialization completes
96 lines
2.6 KiB
C++
96 lines
2.6 KiB
C++
/* ------------------------------------------------------------------------
|
|
Windows NT Service class library
|
|
Copyright Abandoned 1998 Irena Pancirov - Irnet Snc
|
|
This file is public domain and comes with NO WARRANTY of any kind
|
|
-------------------------------------------------------------------------- */
|
|
|
|
// main application thread
|
|
typedef void (*THREAD_FC)(void *);
|
|
|
|
class NTService
|
|
{
|
|
public:
|
|
NTService();
|
|
~NTService();
|
|
|
|
BOOL bOsNT; // true if OS is NT, false for Win95
|
|
//install optinos
|
|
DWORD dwDesiredAccess;
|
|
DWORD dwServiceType;
|
|
DWORD dwStartType;
|
|
DWORD dwErrorControl;
|
|
|
|
LPSTR szLoadOrderGroup;
|
|
LPDWORD lpdwTagID;
|
|
LPSTR szDependencies;
|
|
OSVERSIONINFO osVer;
|
|
|
|
// time-out (in milisec)
|
|
int nStartTimeOut;
|
|
int nStopTimeOut;
|
|
int nPauseTimeOut;
|
|
int nResumeTimeOut;
|
|
|
|
//
|
|
DWORD my_argc;
|
|
LPTSTR *my_argv;
|
|
HANDLE hShutdownEvent;
|
|
int nError;
|
|
DWORD dwState;
|
|
|
|
BOOL GetOS(); // returns TRUE if WinNT
|
|
BOOL IsNT() { return bOsNT;}
|
|
//init service entry point
|
|
long Init(LPCSTR szInternName,void *ServiceThread);
|
|
|
|
//application shutdown event
|
|
void SetShutdownEvent(HANDLE hEvent){ hShutdownEvent=hEvent; }
|
|
|
|
|
|
//service install / un-install
|
|
BOOL Install(int startType,LPCSTR szInternName,LPCSTR szDisplayName,
|
|
LPCSTR szFullPath, LPCSTR szAccountName=NULL,
|
|
LPCSTR szPassword=NULL);
|
|
BOOL SeekStatus(LPCSTR szInternName, int OperationType);
|
|
BOOL Remove(LPCSTR szInternName);
|
|
BOOL IsService(LPCSTR ServiceName);
|
|
BOOL got_service_option(char **argv, char *service_option);
|
|
BOOL is_super_user();
|
|
|
|
/*
|
|
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;
|
|
HANDLE hExitEvent;
|
|
SERVICE_STATUS_HANDLE hServiceStatusHandle;
|
|
BOOL bPause;
|
|
BOOL bRunning;
|
|
HANDLE hThreadHandle;
|
|
THREAD_FC fpServiceThread;
|
|
|
|
void PauseService();
|
|
void ResumeService();
|
|
void StopService();
|
|
BOOL StartService();
|
|
|
|
static void ServiceMain(DWORD argc, LPTSTR *argv);
|
|
static void ServiceCtrlHandler (DWORD ctrlCode);
|
|
|
|
void Exit(DWORD error);
|
|
BOOL SetStatus (DWORD dwCurrentState,DWORD dwWin32ExitCode,
|
|
DWORD dwServiceSpecificExitCode,
|
|
DWORD dwCheckPoint,DWORD dwWaitHint);
|
|
|
|
};
|
|
/* ------------------------- the end -------------------------------------- */
|