Alexandre Julliard : server: Move initial thread creation out of the create_process() function.
Alexandre Julliard
julliard at winehq.org
Thu Sep 20 13:45:33 CDT 2018
Module: wine
Branch: master
Commit: af8f3ae3339336ff23acad5cdaf8d39812146e5d
URL: https://source.winehq.org/git/wine.git/?a=commit;h=af8f3ae3339336ff23acad5cdaf8d39812146e5d
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Sep 20 13:18:19 2018 +0200
server: Move initial thread creation out of the create_process() function.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
server/process.c | 55 +++++++++++++++++++------------------------------------
server/process.h | 2 +-
server/request.c | 7 ++++++-
server/thread.c | 18 ++++++++++++++++++
4 files changed, 44 insertions(+), 38 deletions(-)
diff --git a/server/process.c b/server/process.c
index 8b808de..0698887 100644
--- a/server/process.c
+++ b/server/process.c
@@ -232,16 +232,6 @@ static void add_job_completion( struct job *job, apc_param_t msg, apc_param_t pi
static void add_job_process( struct job *job, struct process *process )
{
- if (!process->running_threads)
- {
- set_error( STATUS_PROCESS_IS_TERMINATING );
- return;
- }
- if (process->job)
- {
- set_error( STATUS_ACCESS_DENIED );
- return;
- }
process->job = (struct job *)grab_object( job );
list_add_tail( &job->process_list, &process->job_entry );
job->num_processes++;
@@ -493,13 +483,11 @@ static void start_sigkill_timer( struct process *process )
process_died( process );
}
-/* create a new process and its main thread */
+/* create a new process */
/* if the function fails the fd is closed */
-struct thread *create_process( int fd, struct thread *parent_thread, int inherit_all )
+struct process *create_process( int fd, struct thread *parent_thread, int inherit_all )
{
struct process *process;
- struct thread *thread = NULL;
- int request_pipe[2];
if (!(process = alloc_object( &process_ops )))
{
@@ -577,24 +565,8 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit
if (!token_assign_label( process->token, security_high_label_sid ))
goto error;
- /* create the main thread */
- if (pipe( request_pipe ) == -1)
- {
- file_set_error();
- goto error;
- }
- if (send_client_fd( process, request_pipe[1], SERVER_PROTOCOL_VERSION ) == -1)
- {
- close( request_pipe[0] );
- close( request_pipe[1] );
- goto error;
- }
- close( request_pipe[1] );
- if (!(thread = create_thread( request_pipe[0], process, NULL ))) goto error;
-
set_fd_events( process->msg_fd, POLLIN ); /* start listening to events */
- release_object( process );
- return thread;
+ return process;
error:
if (process) release_object( process );
@@ -1090,7 +1062,7 @@ DECL_HANDLER(new_process)
{
struct startup_info *info;
struct thread *thread;
- struct process *process;
+ struct process *process = NULL;
struct process *parent = current->process;
int socket_fd = thread_get_inflight_fd( current, req->socket_fd );
@@ -1127,7 +1099,11 @@ DECL_HANDLER(new_process)
if (!req->info_size) /* create an orphaned process */
{
- create_process( socket_fd, NULL, 0 );
+ if ((process = create_process( socket_fd, NULL, 0 )))
+ {
+ create_thread( -1, process, NULL );
+ release_object( process );
+ }
return;
}
@@ -1189,8 +1165,9 @@ DECL_HANDLER(new_process)
#undef FIXUP_LEN
}
- if (!(thread = create_process( socket_fd, current, req->inherit_all ))) goto done;
- process = thread->process;
+ if (!(process = create_process( socket_fd, current, req->inherit_all ))) goto done;
+ if (!(thread = create_thread( -1, process, NULL ))) goto done;
+
process->startup_info = (struct startup_info *)grab_object( info );
if (parent->job
@@ -1252,6 +1229,7 @@ DECL_HANDLER(new_process)
reply->thandle = alloc_handle( parent, thread, req->thread_access, req->thread_attr );
done:
+ if (process) release_object( process );
release_object( info );
}
@@ -1618,7 +1596,12 @@ DECL_HANDLER(assign_job)
if ((process = get_process_from_handle( req->process, PROCESS_SET_QUOTA | PROCESS_TERMINATE )))
{
- add_job_process( job, process );
+ if (!process->running_threads)
+ set_error( STATUS_PROCESS_IS_TERMINATING );
+ else if (process->job)
+ set_error( STATUS_ACCESS_DENIED );
+ else
+ add_job_process( job, process );
release_object( process );
}
release_object( job );
diff --git a/server/process.h b/server/process.h
index f22c128..c9d00aa 100644
--- a/server/process.h
+++ b/server/process.h
@@ -114,7 +114,7 @@ struct process_snapshot
extern unsigned int alloc_ptid( void *ptr );
extern void free_ptid( unsigned int id );
extern void *get_ptid_entry( unsigned int id );
-extern struct thread *create_process( int fd, struct thread *parent_thread, int inherit_all );
+extern struct process *create_process( int fd, struct thread *parent_thread, int inherit_all );
extern data_size_t init_process( struct thread *thread );
extern struct thread *get_process_first_thread( struct process *process );
extern struct process *get_process_from_id( process_id_t id );
diff --git a/server/request.c b/server/request.c
index 2dd84fb..40f532b8 100644
--- a/server/request.c
+++ b/server/request.c
@@ -571,12 +571,17 @@ static void master_socket_poll_event( struct fd *fd, int event )
}
else if (event & POLLIN)
{
+ struct process *process;
struct sockaddr_un dummy;
socklen_t len = sizeof(dummy);
int client = accept( get_unix_fd( master_socket->fd ), (struct sockaddr *) &dummy, &len );
if (client == -1) return;
fcntl( client, F_SETFL, O_NONBLOCK );
- create_process( client, NULL, 0 );
+ if ((process = create_process( client, NULL, 0 )))
+ {
+ create_thread( -1, process, NULL );
+ release_object( process );
+ }
}
}
diff --git a/server/thread.c b/server/thread.c
index 9ee846d..d671377 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -221,6 +221,24 @@ static inline int is_valid_address( client_ptr_t addr )
struct thread *create_thread( int fd, struct process *process, const struct security_descriptor *sd )
{
struct thread *thread;
+ int request_pipe[2];
+
+ if (fd == -1)
+ {
+ if (pipe( request_pipe ) == -1)
+ {
+ file_set_error();
+ return NULL;
+ }
+ if (send_client_fd( process, request_pipe[1], SERVER_PROTOCOL_VERSION ) == -1)
+ {
+ close( request_pipe[0] );
+ close( request_pipe[1] );
+ return NULL;
+ }
+ close( request_pipe[1] );
+ fd = request_pipe[0];
+ }
if (process->is_terminating)
{
More information about the wine-cvs
mailing list