Alexandre Julliard : advapi32: Mark service processes as system processes, and exit when all user processes are done.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Jun 7 07:20:15 CDT 2007


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Jun  6 20:33:30 2007 +0200

advapi32: Mark service processes as system processes, and exit when all user processes are done.

---

 dlls/advapi32/service.c |   27 ++++++++++++++++++++++++---
 1 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c
index 7752b02..4808db1 100644
--- a/dlls/advapi32/service.c
+++ b/dlls/advapi32/service.c
@@ -89,6 +89,8 @@ static CRITICAL_SECTION service_cs = { &service_cs_debug, -1, 0, 0, 0, 0 };
 
 static struct list service_list = LIST_INIT(service_list);
 
+extern HANDLE __wine_make_process_system(void);
+
 /******************************************************************************
  * SC_HANDLEs
  */
@@ -774,18 +776,37 @@ static BOOL service_run_threads(void)
 
     TRACE("starting %d pipe listener threads\n", count);
 
-    handles = HeapAlloc(GetProcessHeap(), 0, sizeof(HANDLE)*count);
+    handles = HeapAlloc(GetProcessHeap(), 0, sizeof(HANDLE) * (count + 1));
+
+    handles[n++] = __wine_make_process_system();
 
     LIST_FOR_EACH_ENTRY( service, &service_list, service_data, entry )
         handles[n++] = CreateThread( NULL, 0, service_control_dispatcher,
                                      service, 0, NULL );
-    assert(n==count);
+    assert(n == count + 1);
 
     LeaveCriticalSection( &service_cs );
 
     /* wait for all the threads to pack up and exit */
-    WaitForMultipleObjectsEx(count, handles, TRUE, INFINITE, FALSE);
+    while (n > 1)
+    {
+        DWORD ret = WaitForMultipleObjects( min(n,MAXIMUM_WAIT_OBJECTS), handles, FALSE, INFINITE );
+        if (!ret)  /* system process event */
+        {
+            TRACE( "last user process exited, shutting down\n" );
+            /* FIXME: we should maybe send a shutdown control to running services */
+            ExitProcess(0);
+        }
+        if (ret < MAXIMUM_WAIT_OBJECTS)
+        {
+            CloseHandle( handles[ret] );
+            memmove( &handles[ret], &handles[ret+1], (n - ret - 1) * sizeof(HANDLE) );
+            n--;
+        }
+        else break;
+    }
 
+    while (n) CloseHandle( handles[--n] );
     HeapFree(GetProcessHeap(), 0, handles);
 
     return TRUE;




More information about the wine-cvs mailing list