From: Rémi Bernon rbernon@codeweavers.com
--- server/process.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-)
diff --git a/server/process.c b/server/process.c index 92f857c4d38..9b3b0b8fc6c 100644 --- a/server/process.c +++ b/server/process.c @@ -139,15 +139,16 @@ static const struct fd_ops process_fd_ops =
struct startup_info { - struct object obj; /* object header */ - struct process *process; /* created process */ - data_size_t info_size; /* size of startup info */ - data_size_t data_size; /* size of whole startup data */ - struct startup_info_data *data; /* data for startup info */ + struct object obj; /* object header */ + struct event_sync *sync; /* sync object for wait/signal */ + struct process *process; /* created process */ + data_size_t info_size; /* size of startup info */ + data_size_t data_size; /* size of whole startup data */ + struct startup_info_data *data; /* data for startup info */ };
static void startup_info_dump( struct object *obj, int verbose ); -static int startup_info_signaled( struct object *obj, struct wait_queue_entry *entry ); +static struct object *startup_info_get_sync( struct object *obj ); static void startup_info_destroy( struct object *obj );
static const struct object_ops startup_info_ops = @@ -155,13 +156,13 @@ static const struct object_ops startup_info_ops = sizeof(struct startup_info), /* size */ &no_type, /* type */ startup_info_dump, /* dump */ - add_queue, /* add_queue */ - remove_queue, /* remove_queue */ - startup_info_signaled, /* signaled */ - no_satisfied, /* satisfied */ + NULL, /* add_queue */ + NULL, /* remove_queue */ + NULL, /* signaled */ + NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ - default_get_sync, /* get_sync */ + startup_info_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -563,7 +564,7 @@ static void set_process_startup_state( struct process *process, enum startup_sta if (process->startup_state == STARTUP_IN_PROGRESS) process->startup_state = state; if (process->startup_info) { - wake_up( &process->startup_info->obj, 0 ); + signal_sync( process->startup_info->sync ); release_object( process->startup_info ); process->startup_info = NULL; } @@ -888,6 +889,7 @@ static void startup_info_destroy( struct object *obj ) assert( obj->ops == &startup_info_ops ); free( info->data ); if (info->process) release_object( info->process ); + if (info->sync) release_object( info->sync ); }
static void startup_info_dump( struct object *obj, int verbose ) @@ -902,10 +904,11 @@ static void startup_info_dump( struct object *obj, int verbose ) fputc( '\n', stderr ); }
-static int startup_info_signaled( struct object *obj, struct wait_queue_entry *entry ) +static struct object *startup_info_get_sync( struct object *obj ) { struct startup_info *info = (struct startup_info *)obj; - return info->process && info->process->startup_state != STARTUP_IN_PROGRESS; + assert( obj->ops == &startup_info_ops ); + return grab_object( info->sync ); }
/* get a process from an id (and increment the refcount) */ @@ -1216,9 +1219,16 @@ DECL_HANDLER(new_process) release_object( parent ); return; } + info->sync = NULL; info->process = NULL; info->data = NULL;
+ if (!(info->sync = create_event_sync( 1, 0 ))) + { + close( socket_fd ); + goto done; + } + info_ptr = get_req_data_after_objattr( objattr, &info->data_size );
if ((req->handles_size & 3) || req->handles_size > info->data_size)