Module: wine Branch: master Commit: 156b205eb527b57d6e9e9e859df77a42c2104603 URL: http://source.winehq.org/git/wine.git/?a=commit;h=156b205eb527b57d6e9e9e859d...
Author: Alexandre Julliard julliard@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 */ +@REQ(make_process_system) +@REPLY + obj_handle_t event; /* event signaled when all user processes have exited */ +@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