This patch avoids simultaneous services startup race and fixes bug 44904. scmdatabase_autostart_services() helper already uses similar approach and unconditionally waits for startup lock. Probably other code paths should use a timeout instead of immediately returning an error after a failure to acquire a startup lock.
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- programs/services/rpc.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/programs/services/rpc.c b/programs/services/rpc.c index 5ecd6601a5..f2b2bc1af1 100644 --- a/programs/services/rpc.c +++ b/programs/services/rpc.c @@ -1202,7 +1202,7 @@ DWORD __cdecl svcctl_StartServiceW( LPCWSTR *lpServiceArgVectors) { struct sc_service_handle *service; - DWORD err; + DWORD err, timeout = 3000;
WINE_TRACE("(%p, %d, %p)\n", hService, dwNumServiceArgs, lpServiceArgVectors);
@@ -1212,8 +1212,12 @@ DWORD __cdecl svcctl_StartServiceW( if (service->service_entry->config.dwStartType == SERVICE_DISABLED) return ERROR_SERVICE_DISABLED;
- if (!scmdatabase_lock_startup(service->service_entry->db)) - return ERROR_SERVICE_DATABASE_LOCKED; + while (!scmdatabase_lock_startup(service->service_entry->db)) + { + Sleep(10); + timeout -= 10; + if (!timeout) return ERROR_SERVICE_DATABASE_LOCKED; + }
err = service_start(service->service_entry, dwNumServiceArgs, lpServiceArgVectors);