Alexandre Julliard : server: Add support for system processes, that can be signaled to exit when all non-system processes are done.

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


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

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

server: Add support for system processes, that can be signaled to exit when all non-system processes are done.

---

 dlls/ntdll/ntdll.spec          |    1 +
 dlls/ntdll/process.c           |   18 ++++++++++++++++++
 include/wine/server_protocol.h |   17 ++++++++++++++++-
 server/process.c               |   40 ++++++++++++++++++++++++++++++++++++++--
 server/process.h               |    1 +
 server/protocol.def            |    7 +++++++
 server/request.h               |    2 ++
 server/trace.c                 |   12 ++++++++++++
 8 files changed, 95 insertions(+), 3 deletions(-)

diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 535f375..b2b0cc0 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -1380,6 +1380,7 @@
 @ cdecl wine_server_handle_to_fd(long long ptr ptr)
 @ cdecl wine_server_release_fd(long long)
 @ cdecl wine_server_send_fd(long)
+@ cdecl __wine_make_process_system()
 
 # Codepages
 @ cdecl __wine_init_codepages(ptr ptr ptr)
diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c
index 724c081..b059c94 100644
--- a/dlls/ntdll/process.c
+++ b/dlls/ntdll/process.c
@@ -71,6 +71,24 @@ PEB * WINAPI RtlGetCurrentPeb(void)
     return NtCurrentTeb()->Peb;
 }
 
+/***********************************************************************
+ *           __wine_make_process_system   (NTDLL.@)
+ *
+ * Mark the current process as a system process.
+ * Returns the event that is signaled when all non-system processes have exited.
+ */
+HANDLE __wine_make_process_system(void)
+{
+    HANDLE ret = 0;
+    SERVER_START_REQ( make_process_system )
+    {
+        if (!wine_server_call( req )) ret = reply->event;
+    }
+    SERVER_END_REQ;
+    return ret;
+}
+
+
 #define UNIMPLEMENTED_INFO_CLASS(c) \
     case c: \
         FIXME("(process=%p) Unimplemented information class: " #c "\n", ProcessHandle); \
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 6b703a1..56574b0 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -4054,6 +4054,18 @@ struct get_next_device_request_reply
 };
 
 
+
+struct make_process_system_request
+{
+    struct request_header __header;
+};
+struct make_process_system_reply
+{
+    struct reply_header __header;
+    obj_handle_t event;
+};
+
+
 enum request
 {
     REQ_new_process,
@@ -4275,6 +4287,7 @@ enum request
     REQ_create_device,
     REQ_delete_device,
     REQ_get_next_device_request,
+    REQ_make_process_system,
     REQ_NB_REQUESTS
 };
 
@@ -4501,6 +4514,7 @@ union generic_request
     struct create_device_request create_device_request;
     struct delete_device_request delete_device_request;
     struct get_next_device_request_request get_next_device_request_request;
+    struct make_process_system_request make_process_system_request;
 };
 union generic_reply
 {
@@ -4725,8 +4739,9 @@ union generic_reply
     struct create_device_reply create_device_reply;
     struct delete_device_reply delete_device_reply;
     struct get_next_device_request_reply get_next_device_request_reply;
+    struct make_process_system_reply make_process_system_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 305
+#define SERVER_PROTOCOL_VERSION 306
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/process.c b/server/process.c
index d733031..623d2ae 100644
--- a/server/process.c
+++ b/server/process.c
@@ -52,7 +52,8 @@
 /* process structure */
 
 static struct list process_list = LIST_INIT(process_list);
-static int running_processes;
+static int running_processes, user_processes;
+static struct event *user_process_event;  /* signaled when all user processes have exited */
 
 /* process operations */
 
@@ -224,6 +225,11 @@ static void set_process_startup_state( struct process *process, enum startup_sta
 static void process_died( struct process *process )
 {
     if (debug_level) fprintf( stderr, "%04x: *process killed*\n", process->id );
+    if (!process->is_system)
+    {
+        if (!--user_processes && user_process_event)
+            set_event( user_process_event );
+    }
     release_object( process );
     if (!--running_processes) close_master_socket();
 }
@@ -272,6 +278,7 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit
     process->priority        = PROCESS_PRIOCLASS_NORMAL;
     process->affinity        = 1;
     process->suspend         = 0;
+    process->is_system       = 0;
     process->create_flags    = 0;
     process->console         = NULL;
     process->startup_state   = STARTUP_IN_PROGRESS;
@@ -616,7 +623,15 @@ static void process_killed( struct process *process )
 void add_process_thread( struct process *process, struct thread *thread )
 {
     list_add_tail( &process->thread_list, &thread->proc_entry );
-    if (!process->running_threads++) running_processes++;
+    if (!process->running_threads++)
+    {
+        running_processes++;
+        if (!process->is_system)
+        {
+            if (!user_processes++ && user_process_event)
+                reset_event( user_process_event );
+        }
+    }
     grab_object( thread );
 }
 
@@ -1143,3 +1158,24 @@ DECL_HANDLER(get_process_idle_event)
         release_object( process );
     }
 }
+
+/* make the current process a system process */
+DECL_HANDLER(make_process_system)
+{
+    struct process *process = current->process;
+
+    if (!user_process_event)
+    {
+        if (!(user_process_event = create_event( NULL, NULL, 0, 1, 0 ))) return;
+        make_object_static( (struct object *)user_process_event );
+    }
+
+    if (!(reply->event = alloc_handle( current->process, user_process_event, EVENT_ALL_ACCESS, 0 )))
+        return;
+
+    if (!process->is_system)
+    {
+        process->is_system = 1;
+        if (!--user_processes) set_event( user_process_event );
+    }
+}
diff --git a/server/process.h b/server/process.h
index b2a6849..3054943 100644
--- a/server/process.h
+++ b/server/process.h
@@ -66,6 +66,7 @@ struct process
     int                  priority;        /* priority class */
     int                  affinity;        /* process affinity mask */
     int                  suspend;         /* global process suspend count */
+    int                  is_system;       /* is it a system process? */
     unsigned int         create_flags;    /* process creation flags */
     struct list          locks;           /* list of file locks owned by the process */
     struct list          classes;         /* window classes owned by the process */
diff --git a/server/protocol.def b/server/protocol.def
index 8a7e5a8..df6b8d3 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2912,3 +2912,10 @@ enum message_type
     data_size_t  out_size;        /* needed output size */
     VARARG(next_data,bytes);      /* input data of the next ioctl */
 @END
+
+
+/* Make the current process a system process */
+ at REQ(make_process_system)
+ at REPLY
+    obj_handle_t event;           /* event signaled when all user processes have exited */
+ at END
diff --git a/server/request.h b/server/request.h
index 90a0c6c..10b6cbe 100644
--- a/server/request.h
+++ b/server/request.h
@@ -329,6 +329,7 @@ DECL_HANDLER(create_device_manager);
 DECL_HANDLER(create_device);
 DECL_HANDLER(delete_device);
 DECL_HANDLER(get_next_device_request);
+DECL_HANDLER(make_process_system);
 
 #ifdef WANT_REQUEST_HANDLERS
 
@@ -554,6 +555,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
     (req_handler)req_create_device,
     (req_handler)req_delete_device,
     (req_handler)req_get_next_device_request,
+    (req_handler)req_make_process_system,
 };
 #endif  /* WANT_REQUEST_HANDLERS */
 
diff --git a/server/trace.c b/server/trace.c
index a340bad..312b68d 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -3530,6 +3530,15 @@ static void dump_get_next_device_request_reply( const struct get_next_device_req
     dump_varargs_bytes( cur_size );
 }
 
+static void dump_make_process_system_request( const struct make_process_system_request *req )
+{
+}
+
+static void dump_make_process_system_reply( const struct make_process_system_reply *req )
+{
+    fprintf( stderr, " event=%p", req->event );
+}
+
 static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_new_process_request,
     (dump_func)dump_get_new_process_info_request,
@@ -3750,6 +3759,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_create_device_request,
     (dump_func)dump_delete_device_request,
     (dump_func)dump_get_next_device_request_request,
+    (dump_func)dump_make_process_system_request,
 };
 
 static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
@@ -3972,6 +3982,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_create_device_reply,
     (dump_func)0,
     (dump_func)dump_get_next_device_request_reply,
+    (dump_func)dump_make_process_system_reply,
 };
 
 static const char * const req_names[REQ_NB_REQUESTS] = {
@@ -4194,6 +4205,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
     "create_device",
     "delete_device",
     "get_next_device_request",
+    "make_process_system",
 };
 
 static const struct




More information about the wine-cvs mailing list