Sebastian Lackner : services: Hold startup lock before calling service_start.

Alexandre Julliard julliard at winehq.org
Thu Aug 18 10:23:24 CDT 2016


Module: wine
Branch: master
Commit: 4c01feb7146a47df41eedd1da0bb540a37d7d7de
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=4c01feb7146a47df41eedd1da0bb540a37d7d7de

Author: Sebastian Lackner <sebastian at fds-team.de>
Date:   Thu Aug 18 09:30:33 2016 +0200

services: Hold startup lock before calling service_start.

Signed-off-by: Sebastian Lackner <sebastian at fds-team.de>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 programs/services/rpc.c      |  9 ++++++---
 programs/services/services.c | 15 ++++-----------
 programs/services/services.h |  2 +-
 3 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/programs/services/rpc.c b/programs/services/rpc.c
index 977ddb6..4cab79e 100644
--- a/programs/services/rpc.c
+++ b/programs/services/rpc.c
@@ -1071,8 +1071,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;
+
     err = service_start(service->service_entry, dwNumServiceArgs, lpServiceArgVectors);
 
+    scmdatabase_unlock_startup(service->service_entry->db);
     return err;
 }
 
@@ -1226,9 +1230,8 @@ DWORD __cdecl svcctl_LockServiceDatabase(
     if ((err = validate_scm_handle(hSCManager, SC_MANAGER_LOCK, &manager)) != ERROR_SUCCESS)
         return err;
 
-    err = scmdatabase_lock_startup(manager->db);
-    if (err != ERROR_SUCCESS)
-        return err;
+    if (!scmdatabase_lock_startup(manager->db))
+        return ERROR_SERVICE_DATABASE_LOCKED;
 
     lock = HeapAlloc(GetProcessHeap(), 0, sizeof(struct sc_lock));
     if (!lock)
diff --git a/programs/services/services.c b/programs/services/services.c
index 177acf1..9156dbc 100644
--- a/programs/services/services.c
+++ b/programs/services/services.c
@@ -352,6 +352,7 @@ static void scmdatabase_autostart_services(struct scmdatabase *db)
     size = i;
 
     scmdatabase_unlock(db);
+    while (!scmdatabase_lock_startup(db)) Sleep(10);
 
     for (i = 0; i < size; i++)
     {
@@ -364,6 +365,7 @@ static void scmdatabase_autostart_services(struct scmdatabase *db)
         release_service(service);
     }
 
+    scmdatabase_unlock_startup(db);
     HeapFree(GetProcessHeap(), 0, services_list);
 }
 
@@ -608,11 +610,9 @@ static DWORD scmdatabase_load_services(struct scmdatabase *db)
     return ERROR_SUCCESS;
 }
 
-DWORD scmdatabase_lock_startup(struct scmdatabase *db)
+BOOL scmdatabase_lock_startup(struct scmdatabase *db)
 {
-    if (InterlockedCompareExchange(&db->service_start_lock, TRUE, FALSE))
-        return ERROR_SERVICE_DATABASE_LOCKED;
-    return ERROR_SUCCESS;
+    return !InterlockedCompareExchange(&db->service_start_lock, TRUE, FALSE);
 }
 
 void scmdatabase_unlock_startup(struct scmdatabase *db)
@@ -904,10 +904,6 @@ DWORD service_start(struct service_entry *service, DWORD service_argc, LPCWSTR *
     struct process_entry *process = NULL;
     DWORD err;
 
-    err = scmdatabase_lock_startup(service->db);
-    if (err != ERROR_SUCCESS)
-        return err;
-
     err = service_start_process(service, &process);
     if (err == ERROR_SUCCESS)
     {
@@ -928,10 +924,7 @@ DWORD service_start(struct service_entry *service, DWORD service_argc, LPCWSTR *
         release_process(process);
     }
 
-    scmdatabase_unlock_startup(service->db);
-
     WINE_TRACE("returning %d\n", err);
-
     return err;
 }
 
diff --git a/programs/services/services.h b/programs/services/services.h
index a3ecdf2..fb1374e 100644
--- a/programs/services/services.h
+++ b/programs/services/services.h
@@ -72,7 +72,7 @@ struct service_entry *scmdatabase_find_service(struct scmdatabase *db, LPCWSTR n
 struct service_entry *scmdatabase_find_service_by_displayname(struct scmdatabase *db, LPCWSTR name);
 DWORD scmdatabase_add_service(struct scmdatabase *db, struct service_entry *entry);
 
-DWORD scmdatabase_lock_startup(struct scmdatabase *db);
+BOOL scmdatabase_lock_startup(struct scmdatabase *db);
 void scmdatabase_unlock_startup(struct scmdatabase *db);
 
 void scmdatabase_lock(struct scmdatabase *db);




More information about the wine-cvs mailing list