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

This commit is contained in:
Alexandre Julliard 2007-06-06 20:33:13 +02:00
parent 1ab9649079
commit 156b205eb5
8 changed files with 95 additions and 3 deletions

View File

@ -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)

View File

@ -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); \

View File

@ -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 */

View File

@ -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 );
}
}

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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