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