mirror of
https://github.com/reactos/reactos.git
synced 2024-12-31 19:42:51 +00:00
[SERVICES] Fix timeout when a service is stopped
RSetServiceStatus: Send the stop command for the dispatcher thread from a separate thread. Fixes CORE-15064
This commit is contained in:
parent
2a182931b6
commit
f6d81f2257
1 changed files with 50 additions and 9 deletions
|
@ -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 */
|
/* Function 7 */
|
||||||
DWORD
|
DWORD
|
||||||
WINAPI
|
WINAPI
|
||||||
|
@ -1683,6 +1720,8 @@ RSetServiceStatus(
|
||||||
DWORD dwPreviousType;
|
DWORD dwPreviousType;
|
||||||
LPCWSTR lpLogStrings[2];
|
LPCWSTR lpLogStrings[2];
|
||||||
WCHAR szLogBuffer[80];
|
WCHAR szLogBuffer[80];
|
||||||
|
HANDLE hStopThread = NULL;
|
||||||
|
DWORD dwStopThreadId;
|
||||||
UINT uID;
|
UINT uID;
|
||||||
|
|
||||||
DPRINT("RSetServiceStatus() called\n");
|
DPRINT("RSetServiceStatus() called\n");
|
||||||
|
@ -1762,15 +1801,17 @@ RSetServiceStatus(
|
||||||
/* If we just stopped the last running service... */
|
/* If we just stopped the last running service... */
|
||||||
if (lpService->lpImage->dwImageRunCount == 0)
|
if (lpService->lpImage->dwImageRunCount == 0)
|
||||||
{
|
{
|
||||||
/* Stop the dispatcher thread */
|
/* Run the stop thread to stop the service dispatcher */
|
||||||
ScmControlService(lpService->lpImage->hControlPipe,
|
hStopThread = CreateThread(NULL,
|
||||||
L"",
|
0,
|
||||||
(SERVICE_STATUS_HANDLE)lpService,
|
(LPTHREAD_START_ROUTINE)ScmStopThread,
|
||||||
SERVICE_CONTROL_STOP);
|
(LPVOID)lpService,
|
||||||
|
0,
|
||||||
/* Remove the service image */
|
&dwStopThreadId);
|
||||||
ScmRemoveServiceImage(lpService->lpImage);
|
if (hStopThread != NULL)
|
||||||
lpService->lpImage = NULL;
|
{
|
||||||
|
CloseHandle(hStopThread);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue