https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6b15e72206a5511ea1cd3a734ce3155e3668d084

commit 6b15e72206a5511ea1cd3a734ce3155e3668d084
Author:     Eric Kohl <[email protected]>
AuthorDate: Sun Jul 28 22:37:17 2019 +0200
Commit:     Eric Kohl <[email protected]>
CommitDate: Sun Jul 28 22:38:04 2019 +0200

    [W32TIME] Use an event to stop the service
    
    CORE-16180
---
 base/services/w32time/w32time.c | 52 +++++++++++++++++++++++++++--------------
 1 file changed, 35 insertions(+), 17 deletions(-)

diff --git a/base/services/w32time/w32time.c b/base/services/w32time/w32time.c
index d6a6828b637..590396fc771 100644
--- a/base/services/w32time/w32time.c
+++ b/base/services/w32time/w32time.c
@@ -12,6 +12,7 @@
 
 SERVICE_STATUS ServiceStatus;
 SERVICE_STATUS_HANDLE hStatus;
+HANDLE hStopEvent = NULL;
 static WCHAR ServiceName[] = L"W32Time";
 
 int InitService(VOID);
@@ -208,28 +209,21 @@ ControlHandler(DWORD request)
     switch (request)
     {
         case SERVICE_CONTROL_STOP:
-            DPRINT("W32Time Service stopped.\n");
-
-            ServiceStatus.dwWin32ExitCode = 0;
-            ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
-            SetServiceStatus(hStatus, &ServiceStatus);
-            return;
-
         case SERVICE_CONTROL_SHUTDOWN:
-            DPRINT("W32Time Service stopped.\n");
+            DPRINT("Stopping W32Time Service\n");
 
             ServiceStatus.dwWin32ExitCode = 0;
-            ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
+            ServiceStatus.dwCurrentState  = SERVICE_STOP_PENDING;
             SetServiceStatus(hStatus, &ServiceStatus);
+
+            if (hStopEvent)
+                SetEvent(hStopEvent);
             return;
 
         default:
             break;
     }
 
-    /* Report current status */
-    SetServiceStatus(hStatus, &ServiceStatus);
-
     return;
 }
 
@@ -239,7 +233,7 @@ WINAPI
 ServiceMain(DWORD argc, LPWSTR *argv)
 {
     int   result;
-    DWORD dwPollInterval;
+    DWORD dwInterval;
 
     UNREFERENCED_PARAMETER(argc);
     UNREFERENCED_PARAMETER(argv);
@@ -260,14 +254,27 @@ ServiceMain(DWORD argc, LPWSTR *argv)
         return;
     }
 
+    /* Create the stop event */
+    hStopEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+    if (hStopEvent == NULL)
+    {
+        ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
+        ServiceStatus.dwWin32ExitCode = GetLastError();
+        ServiceStatus.dwControlsAccepted = 0;
+        SetServiceStatus(hStatus, &ServiceStatus);
+        return;
+    }
+
+    /* Get the interval */
+    dwInterval = GetIntervalSetting();
+
     /* We report the running status to SCM. */
     ServiceStatus.dwCurrentState = SERVICE_RUNNING;
     SetServiceStatus(hStatus, &ServiceStatus);
 
     /* The worker loop of a service */
-    while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
+    for (;;)
     {
-        dwPollInterval = GetIntervalSetting();
         result = SetTime();
 
         if (result)
@@ -284,13 +291,24 @@ ServiceMain(DWORD argc, LPWSTR *argv)
              * service when the correct conditions can be determined, but it
              * is left commented out.
             ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
-            ServiceStatus.dwWin32ExitCode = -1;
+            ServiceStatus.dwWin32ExitCode = result;
             SetServiceStatus(hStatus, &ServiceStatus);
             return;
             */
         }
 
-        Sleep(dwPollInterval * 1000);
+        if (WaitForSingleObject(hStopEvent, dwInterval) == WAIT_OBJECT_0)
+        {
+            CloseHandle(hStopEvent);
+            hStopEvent = NULL;
+
+            ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
+            ServiceStatus.dwWin32ExitCode = ERROR_SUCCESS;
+            ServiceStatus.dwControlsAccepted = 0;
+            SetServiceStatus(hStatus, &ServiceStatus);
+            DPRINT("Stopped W32Time Service\n");
+            return;
+        }
     }
     return;
 }

Reply via email to