From ec7bb2391d82386213ba5a2740114188e9467eca Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 12 Nov 1999 03:35:25 +0000 Subject: [PATCH] Added support for CREATE_SUSPENDED flag in CreateProcess. --- include/server.h | 9 +++++++++ loader/module.c | 2 -- scheduler/process.c | 23 +++++++++-------------- server/process.c | 26 +++++++++++++++++++++++++- server/process.h | 1 + server/request.h | 2 ++ server/thread.c | 3 ++- server/trace.c | 9 +++++++++ 8 files changed, 57 insertions(+), 18 deletions(-) diff --git a/include/server.h b/include/server.h index 653296e6038..2eada6e8909 100644 --- a/include/server.h +++ b/include/server.h @@ -33,6 +33,7 @@ struct new_process_request IN int hstdin; /* handle for stdin */ IN int hstdout; /* handle for stdout */ IN int hstderr; /* handle for stderr */ + IN int event; /* event to signal startup */ IN int cmd_show; /* main window show mode */ IN void* env_ptr; /* pointer to environment (FIXME: hack) */ OUT void* pid; /* process id */ @@ -72,6 +73,13 @@ struct init_process_request }; +/* Signal the end of the process initialization */ +struct init_process_done_request +{ + IN int dummy; +}; + + /* Initialize a thread; called from the child after fork()/clone() */ struct init_thread_request { @@ -808,6 +816,7 @@ enum request REQ_NEW_THREAD, REQ_SET_DEBUG, REQ_INIT_PROCESS, + REQ_INIT_PROCESS_DONE, REQ_INIT_THREAD, REQ_GET_THREAD_BUFFER, REQ_TERMINATE_PROCESS, diff --git a/loader/module.c b/loader/module.c index be6a9942300..f0173231bba 100644 --- a/loader/module.c +++ b/loader/module.c @@ -1113,8 +1113,6 @@ BOOL WINAPI CreateProcessA( LPCSTR lpApplicationName, LPSTR lpCommandLine, /* Warn if unsupported features are used */ - if (dwCreationFlags & CREATE_SUSPENDED) - FIXME_(module)("(%s,...): CREATE_SUSPENDED ignored\n", name); if (dwCreationFlags & DETACHED_PROCESS) FIXME_(module)("(%s,...): DETACHED_PROCESS ignored\n", name); if (dwCreationFlags & CREATE_NEW_CONSOLE) diff --git a/scheduler/process.c b/scheduler/process.c index b5f3b4e4641..b115863e142 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -446,9 +446,7 @@ void PROCESS_Start(void) PROCESS_CallUserSignalProc( USIG_PROCESS_INIT, 0 ); /* Signal the parent process to continue */ - SetEvent( pdb->load_done_evt ); - CloseHandle( pdb->load_done_evt ); - pdb->load_done_evt = INVALID_HANDLE_VALUE; + server_call( REQ_INIT_PROCESS_DONE ); /* Perform Win32 specific process initialization */ if ( type == PROC_WIN32 ) @@ -523,7 +521,7 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, BOOL inherit, DWORD flags, STARTUPINFOA *startup, PROCESS_INFORMATION *info ) { - HANDLE handles[2], load_done_evt = INVALID_HANDLE_VALUE; + HANDLE handles[2], load_done_evt = 0; DWORD exitcode, size; BOOL alloc_stack16; int server_thandle; @@ -534,13 +532,15 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, if (!pdb) return NULL; info->hThread = info->hProcess = INVALID_HANDLE_VALUE; - + if (!(load_done_evt = CreateEventA( NULL, TRUE, FALSE, NULL ))) goto error; + /* Create the process on the server side */ req->inherit = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle); req->inherit_all = inherit; req->create_flags = flags; req->start_flags = startup->dwFlags; + req->event = load_done_evt; if (startup->dwFlags & STARTF_USESTDHANDLES) { req->hstdin = startup->hStdInput; @@ -588,17 +588,12 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, /* Create the main thread */ - if (!(teb = THREAD_Create( pdb, 0L, size, alloc_stack16, tsa, &server_thandle ))) - goto error; + if (!(teb = THREAD_Create( pdb, flags & CREATE_SUSPENDED, size, + alloc_stack16, tsa, &server_thandle ))) goto error; info->hThread = server_thandle; info->dwThreadId = (DWORD)teb->tid; teb->startup = PROCESS_Start; - /* Create the load-done event */ - load_done_evt = CreateEventA( NULL, TRUE, FALSE, NULL ); - DuplicateHandle( GetCurrentProcess(), load_done_evt, - info->hProcess, &pdb->load_done_evt, 0, TRUE, DUPLICATE_SAME_ACCESS ); - /* Pass module to new process (FIXME: hack) */ pdb->module = pModule->self; SYSDEPS_SpawnThread( teb ); @@ -634,12 +629,12 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, } CloseHandle( load_done_evt ); - load_done_evt = INVALID_HANDLE_VALUE; + load_done_evt = 0; return pdb; error: - if (load_done_evt != INVALID_HANDLE_VALUE) CloseHandle( load_done_evt ); + if (load_done_evt) CloseHandle( load_done_evt ); if (info->hThread != INVALID_HANDLE_VALUE) CloseHandle( info->hThread ); if (info->hProcess != INVALID_HANDLE_VALUE) CloseHandle( info->hProcess ); PROCESS_FreePDB( pdb ); diff --git a/server/process.c b/server/process.c index 17fa8cc4c69..f5ce22039f8 100644 --- a/server/process.c +++ b/server/process.c @@ -70,6 +70,7 @@ static struct process *create_process( struct process *parent, struct new_proces process->suspend = 0; process->console_in = NULL; process->console_out = NULL; + process->init_event = NULL; process->info = NULL; gettimeofday( &process->start_time, NULL ); @@ -87,6 +88,13 @@ static struct process *create_process( struct process *parent, struct new_proces memcpy( process->info->cmdline, cmd_line, len ); process->info->cmdline[len] = 0; + /* get the init done event */ + if (req->event != -1) + { + if (!(process->init_event = get_event_obj( parent, req->event, EVENT_MODIFY_STATE ))) + goto error; + } + /* set the process console */ if (req->create_flags & CREATE_NEW_CONSOLE) { @@ -120,7 +128,6 @@ static struct process *create_process( struct process *parent, struct new_proces error: free_console( process ); - if (process->info) free( process->info ); if (process->handles) release_object( process->handles ); release_object( process ); return NULL; @@ -139,6 +146,7 @@ struct process *create_initial_process(void) req.hstdin = -1; req.hstdout = -1; req.hstderr = -1; + req.event = -1; req.cmd_show = 0; req.env_ptr = NULL; if ((process = create_process( NULL, &req, "", 1 ))) @@ -165,6 +173,7 @@ static void process_destroy( struct object *obj ) if (process->prev) process->prev->next = process->next; else first_process = process->next; if (process->info) free( process->info ); + if (process->init_event) release_object( process->init_event ); } /* dump a process on stdout for debugging purposes */ @@ -369,6 +378,21 @@ DECL_HANDLER(init_process) free( info ); } +/* signal the end of the process initialization */ +DECL_HANDLER(init_process_done) +{ + struct process *process = current->process; + if (!process->init_event) + { + fatal_protocol_error( current, "init_process_done: no event\n" ); + return; + } + set_event( process->init_event ); + release_object( process->init_event ); + process->init_event = NULL; + if (current->suspend + current->process->suspend > 0) stop_thread( current ); +} + /* open a handle to a process */ DECL_HANDLER(open_process) { diff --git a/server/process.h b/server/process.h index b141dc98772..08edd0b0b60 100644 --- a/server/process.h +++ b/server/process.h @@ -34,6 +34,7 @@ struct process int suspend; /* global process suspend count */ struct object *console_in; /* console input */ struct object *console_out; /* console output */ + struct event *init_event; /* event for init done */ struct new_process_request *info; /* startup info (freed after startup) */ }; diff --git a/server/request.h b/server/request.h index c111d4dc65e..6ee07e67b6b 100644 --- a/server/request.h +++ b/server/request.h @@ -65,6 +65,7 @@ DECL_HANDLER(new_process); DECL_HANDLER(new_thread); DECL_HANDLER(set_debug); DECL_HANDLER(init_process); +DECL_HANDLER(init_process_done); DECL_HANDLER(init_thread); DECL_HANDLER(get_thread_buffer); DECL_HANDLER(terminate_process); @@ -142,6 +143,7 @@ static const struct handler { { (void(*)())req_new_thread, sizeof(struct new_thread_request) }, { (void(*)())req_set_debug, sizeof(struct set_debug_request) }, { (void(*)())req_init_process, sizeof(struct init_process_request) }, + { (void(*)())req_init_process_done, sizeof(struct init_process_done_request) }, { (void(*)())req_init_thread, sizeof(struct init_thread_request) }, { (void(*)())req_get_thread_buffer, sizeof(struct get_thread_buffer_request) }, { (void(*)())req_terminate_process, sizeof(struct terminate_process_request) }, diff --git a/server/thread.c b/server/thread.c index 89fd690a5f4..1861fc9ebc0 100644 --- a/server/thread.c +++ b/server/thread.c @@ -318,7 +318,8 @@ static void detach_thread( struct thread *thread ) /* stop a thread (at the Unix level) */ void stop_thread( struct thread *thread ) { - if (!thread->unix_pid) return; + /* can't stop a thread while initialisation is in progress */ + if (!thread->unix_pid || thread->process->init_event) return; /* first try to attach to it */ if (!thread->attached) if (attach_thread( thread )) return; /* this will have stopped it */ diff --git a/server/trace.c b/server/trace.c index 098b3c22690..1af1367eb32 100644 --- a/server/trace.c +++ b/server/trace.c @@ -52,6 +52,7 @@ static void dump_new_process_request( struct new_process_request *req ) fprintf( stderr, " hstdin=%d,", req->hstdin ); fprintf( stderr, " hstdout=%d,", req->hstdout ); fprintf( stderr, " hstderr=%d,", req->hstderr ); + fprintf( stderr, " event=%d,", req->event ); fprintf( stderr, " cmd_show=%d,", req->cmd_show ); fprintf( stderr, " env_ptr=%p,", req->env_ptr ); fprintf( stderr, " cmdline=\"%s\"", req->cmdline ); @@ -96,6 +97,11 @@ static void dump_init_process_reply( struct init_process_request *req ) fprintf( stderr, " cmdline=\"%s\"", req->cmdline ); } +static void dump_init_process_done_request( struct init_process_done_request *req ) +{ + fprintf( stderr, " dummy=%d", req->dummy ); +} + static void dump_init_thread_request( struct init_thread_request *req ) { fprintf( stderr, " unix_pid=%d,", req->unix_pid ); @@ -762,6 +768,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_new_thread_request, (dump_func)dump_set_debug_request, (dump_func)dump_init_process_request, + (dump_func)dump_init_process_done_request, (dump_func)dump_init_thread_request, (dump_func)dump_get_thread_buffer_request, (dump_func)dump_terminate_process_request, @@ -835,6 +842,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_new_thread_reply, (dump_func)0, (dump_func)dump_init_process_reply, + (dump_func)0, (dump_func)dump_init_thread_reply, (dump_func)0, (dump_func)0, @@ -908,6 +916,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "new_thread", "set_debug", "init_process", + "init_process_done", "init_thread", "get_thread_buffer", "terminate_process", -- 2.11.4.GIT