[PATCH] programs/services: Add a 3000 ms timeout to StartService.

Dmitry Timoshkov dmitry at baikal.ru
Mon Apr 9 03:23:43 CDT 2018


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 at 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);
 
-- 
2.16.3




More information about the wine-devel mailing list