Hey Eric,
What's the purpose of that "Sleep(2000);"? Is it a debug leftover?
Cheers,
Pierre
Le 05/10/2018 à 08:43, Eric Kohl a écrit :
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f6d81f225747e4b1b3716…
 commit f6d81f225747e4b1b3716e9ca8629f77dcc52b1a
 Author:     Eric Kohl <eric.kohl(a)reactos.org>
 AuthorDate: Fri Oct 5 08:41:23 2018 +0200
 Commit:     Eric Kohl <eric.kohl(a)reactos.org>
 CommitDate: Fri Oct 5 08:41:23 2018 +0200
     [SERVICES] Fix timeout when a service is stopped
     RSetServiceStatus: Send the stop command for the dispatcher thread from a separate
thread.
     Fixes CORE-15064
 ---
  base/system/services/rpcserver.c | 59 ++++++++++++++++++++++++++++++++++------
  1 file changed, 50 insertions(+), 9 deletions(-)
 diff --git a/base/system/services/rpcserver.c b/base/system/services/rpcserver.c
 index 7f251c8760..8e383a5bdc 100644
 --- a/base/system/services/rpcserver.c
 +++ b/base/system/services/rpcserver.c
 @@ -1671,6 +1671,43 @@ ScmIsValidServiceState(DWORD dwCurrentState)
  }
 +static
 +DWORD
 +WINAPI
 +ScmStopThread(
 +    _In_ PVOID pParam)
 +{
 +    PSERVICE pService;
 +
 +    DPRINT("ScmStopThread(%p)\n", pParam);
 +
 +    pService = (PSERVICE)pParam;
 +
 +    if (pService->lpImage->dwImageRunCount != 0)
 +        return 0;
 +
 +    Sleep(2000);
 +
 +    /* Lock the service database exclusively */
 +    ScmLockDatabaseExclusive();
 +
 +    /* Stop the dispatcher thread */
 +    ScmControlService(pService->lpImage->hControlPipe,
 +                      L"",
 +                      (SERVICE_STATUS_HANDLE)pService,
 +                      SERVICE_CONTROL_STOP);
 +
 +    /* Remove the service image */
 +    ScmRemoveServiceImage(pService->lpImage);
 +
 +    /* Unlock the service database */
 +    ScmUnlockDatabase();
 +
 +    DPRINT("ScmStopThread done!\n");
 +    return 0;
 +}
 +
 +
  /* Function 7 */
  DWORD
  WINAPI
 @@ -1683,6 +1720,8 @@ RSetServiceStatus(
      DWORD dwPreviousType;
      LPCWSTR lpLogStrings[2];
      WCHAR szLogBuffer[80];
 +    HANDLE hStopThread = NULL;
 +    DWORD dwStopThreadId;
      UINT uID;
      DPRINT("RSetServiceStatus() called\n");
 @@ -1762,15 +1801,17 @@ RSetServiceStatus(
          /* If we just stopped the last running service... */
          if (lpService->lpImage->dwImageRunCount == 0)
          {
 -            /* Stop the dispatcher thread */
 -            ScmControlService(lpService->lpImage->hControlPipe,
 -                              L"",
 -                              (SERVICE_STATUS_HANDLE)lpService,
 -                              SERVICE_CONTROL_STOP);
 -
 -            /* Remove the service image */
 -            ScmRemoveServiceImage(lpService->lpImage);
 -            lpService->lpImage = NULL;
 +           /* Run the stop thread to stop the service dispatcher */
 +           hStopThread = CreateThread(NULL,
 +                                      0,
 +                                      (LPTHREAD_START_ROUTINE)ScmStopThread,
 +                                      (LPVOID)lpService,
 +                                      0,
 +                                      &dwStopThreadId);
 +           if (hStopThread != NULL)
 +           {
 +               CloseHandle(hStopThread);
 +           }
          }
      }
  
 
--
Pierre Schweitzer <pierre at reactos.org>
System & Network Administrator
Senior Kernel Developer
ReactOS Deutschland e.V.