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=f6d81f225747e4b1b3716e...
commit f6d81f225747e4b1b3716e9ca8629f77dcc52b1a Author: Eric Kohl eric.kohl@reactos.org AuthorDate: Fri Oct 5 08:41:23 2018 +0200 Commit: Eric Kohl eric.kohl@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); }} }