A few optimizations in the process startup requests now that Winelib
apps are started differently from Unix ones.
This commit is contained in:
parent
32886f6b88
commit
9d80215254
|
@ -214,7 +214,7 @@ struct get_new_process_info_reply
|
||||||
handle_t phandle;
|
handle_t phandle;
|
||||||
void* tid;
|
void* tid;
|
||||||
handle_t thandle;
|
handle_t thandle;
|
||||||
handle_t event;
|
int success;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -258,7 +258,6 @@ struct init_process_reply
|
||||||
struct reply_header __header;
|
struct reply_header __header;
|
||||||
int create_flags;
|
int create_flags;
|
||||||
unsigned int server_start;
|
unsigned int server_start;
|
||||||
handle_t info;
|
|
||||||
size_t info_size;
|
size_t info_size;
|
||||||
handle_t exe_file;
|
handle_t exe_file;
|
||||||
handle_t hstdin;
|
handle_t hstdin;
|
||||||
|
@ -271,8 +270,6 @@ struct init_process_reply
|
||||||
struct get_startup_info_request
|
struct get_startup_info_request
|
||||||
{
|
{
|
||||||
struct request_header __header;
|
struct request_header __header;
|
||||||
handle_t info;
|
|
||||||
int close;
|
|
||||||
};
|
};
|
||||||
struct get_startup_info_reply
|
struct get_startup_info_reply
|
||||||
{
|
{
|
||||||
|
@ -3198,6 +3195,6 @@ union generic_reply
|
||||||
struct get_window_properties_reply get_window_properties_reply;
|
struct get_window_properties_reply get_window_properties_reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 79
|
#define SERVER_PROTOCOL_VERSION 80
|
||||||
|
|
||||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
|
|
@ -201,8 +201,7 @@ inline static char *copy_str( char **dst, const char **src, size_t len )
|
||||||
*
|
*
|
||||||
* Fill the startup info structure from the server.
|
* Fill the startup info structure from the server.
|
||||||
*/
|
*/
|
||||||
ENVDB *ENV_InitStartupInfo( handle_t info_handle, size_t info_size,
|
ENVDB *ENV_InitStartupInfo( size_t info_size, char *main_exe_name, size_t main_exe_size )
|
||||||
char *main_exe_name, size_t main_exe_size )
|
|
||||||
{
|
{
|
||||||
startup_info_t info;
|
startup_info_t info;
|
||||||
void *data;
|
void *data;
|
||||||
|
@ -217,8 +216,6 @@ ENVDB *ENV_InitStartupInfo( handle_t info_handle, size_t info_size,
|
||||||
|
|
||||||
SERVER_START_REQ( get_startup_info )
|
SERVER_START_REQ( get_startup_info )
|
||||||
{
|
{
|
||||||
req->info = info_handle;
|
|
||||||
req->close = TRUE;
|
|
||||||
wine_server_set_reply( req, data, info_size );
|
wine_server_set_reply( req, data, info_size );
|
||||||
wine_server_call( req );
|
wine_server_call( req );
|
||||||
info_size = wine_server_reply_size( reply );
|
info_size = wine_server_reply_size( reply );
|
||||||
|
|
|
@ -118,8 +118,8 @@ static int main_create_flags;
|
||||||
static unsigned int server_startticks;
|
static unsigned int server_startticks;
|
||||||
|
|
||||||
/* memory/environ.c */
|
/* memory/environ.c */
|
||||||
extern struct _ENVDB *ENV_InitStartupInfo( handle_t info_handle, size_t info_size,
|
extern struct _ENVDB *ENV_InitStartupInfo( size_t info_size, char *main_exe_name,
|
||||||
char *main_exe_name, size_t main_exe_size );
|
size_t main_exe_size );
|
||||||
extern BOOL ENV_BuildCommandLine( char **argv );
|
extern BOOL ENV_BuildCommandLine( char **argv );
|
||||||
extern STARTUPINFOA current_startupinfo;
|
extern STARTUPINFOA current_startupinfo;
|
||||||
|
|
||||||
|
@ -358,7 +358,6 @@ static BOOL process_init( char *argv[] )
|
||||||
{
|
{
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
size_t info_size = 0;
|
size_t info_size = 0;
|
||||||
handle_t info = 0;
|
|
||||||
|
|
||||||
/* store the program name */
|
/* store the program name */
|
||||||
argv0 = argv[0];
|
argv0 = argv[0];
|
||||||
|
@ -384,7 +383,6 @@ static BOOL process_init( char *argv[] )
|
||||||
main_exe_file = reply->exe_file;
|
main_exe_file = reply->exe_file;
|
||||||
main_create_flags = reply->create_flags;
|
main_create_flags = reply->create_flags;
|
||||||
info_size = reply->info_size;
|
info_size = reply->info_size;
|
||||||
info = reply->info;
|
|
||||||
server_startticks = reply->server_start;
|
server_startticks = reply->server_start;
|
||||||
current_startupinfo.hStdInput = reply->hstdin;
|
current_startupinfo.hStdInput = reply->hstdin;
|
||||||
current_startupinfo.hStdOutput = reply->hstdout;
|
current_startupinfo.hStdOutput = reply->hstdout;
|
||||||
|
@ -420,12 +418,12 @@ static BOOL process_init( char *argv[] )
|
||||||
PTHREAD_init_done();
|
PTHREAD_init_done();
|
||||||
|
|
||||||
/* Copy the parent environment */
|
/* Copy the parent environment */
|
||||||
if (!(current_process.env_db = ENV_InitStartupInfo( info, info_size,
|
if (!(current_process.env_db = ENV_InitStartupInfo( info_size, main_exe_name,
|
||||||
main_exe_name, sizeof(main_exe_name) )))
|
sizeof(main_exe_name) )))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Parse command line arguments */
|
/* Parse command line arguments */
|
||||||
OPTIONS_ParseOptions( !info ? argv : NULL );
|
OPTIONS_ParseOptions( !info_size ? argv : NULL );
|
||||||
|
|
||||||
ret = MAIN_MainInit();
|
ret = MAIN_MainInit();
|
||||||
|
|
||||||
|
@ -891,8 +889,7 @@ static BOOL create_process( HANDLE hFile, LPCSTR filename, LPSTR cmd_line, LPCST
|
||||||
BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
|
BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
|
||||||
LPPROCESS_INFORMATION info, LPCSTR unixdir )
|
LPPROCESS_INFORMATION info, LPCSTR unixdir )
|
||||||
{
|
{
|
||||||
BOOL ret;
|
BOOL ret, success = FALSE;
|
||||||
HANDLE load_done_evt = 0;
|
|
||||||
HANDLE process_info;
|
HANDLE process_info;
|
||||||
startup_info_t startup_info;
|
startup_info_t startup_info;
|
||||||
|
|
||||||
|
@ -965,48 +962,33 @@ static BOOL create_process( HANDLE hFile, LPCSTR filename, LPSTR cmd_line, LPCST
|
||||||
|
|
||||||
/* wait for the new process info to be ready */
|
/* wait for the new process info to be ready */
|
||||||
|
|
||||||
ret = TRUE; /* pretend success even if we don't get the new process info */
|
WaitForSingleObject( process_info, INFINITE );
|
||||||
if (WaitForSingleObject( process_info, 2000 ) == STATUS_WAIT_0)
|
SERVER_START_REQ( get_new_process_info )
|
||||||
{
|
{
|
||||||
SERVER_START_REQ( get_new_process_info )
|
req->info = process_info;
|
||||||
|
req->pinherit = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle);
|
||||||
|
req->tinherit = (tsa && (tsa->nLength >= sizeof(*tsa)) && tsa->bInheritHandle);
|
||||||
|
if ((ret = !wine_server_call_err( req )))
|
||||||
{
|
{
|
||||||
req->info = process_info;
|
info->dwProcessId = (DWORD)reply->pid;
|
||||||
req->pinherit = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle);
|
info->dwThreadId = (DWORD)reply->tid;
|
||||||
req->tinherit = (tsa && (tsa->nLength >= sizeof(*tsa)) && tsa->bInheritHandle);
|
info->hProcess = reply->phandle;
|
||||||
if ((ret = !wine_server_call_err( req )))
|
info->hThread = reply->thandle;
|
||||||
{
|
success = reply->success;
|
||||||
info->dwProcessId = (DWORD)reply->pid;
|
|
||||||
info->dwThreadId = (DWORD)reply->tid;
|
|
||||||
info->hProcess = reply->phandle;
|
|
||||||
info->hThread = reply->thandle;
|
|
||||||
load_done_evt = reply->event;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
}
|
||||||
|
SERVER_END_REQ;
|
||||||
|
|
||||||
|
if (ret && !success) /* new process failed to start */
|
||||||
|
{
|
||||||
|
DWORD exitcode;
|
||||||
|
if (GetExitCodeProcess( info->hProcess, &exitcode )) SetLastError( exitcode );
|
||||||
|
CloseHandle( info->hThread );
|
||||||
|
CloseHandle( info->hProcess );
|
||||||
|
ret = FALSE;
|
||||||
}
|
}
|
||||||
CloseHandle( process_info );
|
CloseHandle( process_info );
|
||||||
if (!ret) return FALSE;
|
return ret;
|
||||||
|
|
||||||
/* Wait until process is initialized (or initialization failed) */
|
|
||||||
if (load_done_evt)
|
|
||||||
{
|
|
||||||
DWORD res;
|
|
||||||
HANDLE handles[2];
|
|
||||||
|
|
||||||
handles[0] = info->hProcess;
|
|
||||||
handles[1] = load_done_evt;
|
|
||||||
res = WaitForMultipleObjects( 2, handles, FALSE, INFINITE );
|
|
||||||
CloseHandle( load_done_evt );
|
|
||||||
if (res == STATUS_WAIT_0) /* the process died */
|
|
||||||
{
|
|
||||||
DWORD exitcode;
|
|
||||||
if (GetExitCodeProcess( info->hProcess, &exitcode )) SetLastError( exitcode );
|
|
||||||
CloseHandle( info->hThread );
|
|
||||||
CloseHandle( info->hProcess );
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -427,7 +427,7 @@ static int debugger_attach( struct process *process, struct thread *debugger )
|
||||||
struct thread *thread;
|
struct thread *thread;
|
||||||
|
|
||||||
if (process->debugger) goto error; /* already being debugged */
|
if (process->debugger) goto error; /* already being debugged */
|
||||||
if (process->init_event) goto error; /* still starting up */
|
if (!is_process_init_done( process )) goto error; /* still starting up */
|
||||||
if (!process->thread_list) goto error; /* no thread running in the process */
|
if (!process->thread_list) goto error; /* no thread running in the process */
|
||||||
|
|
||||||
/* make sure we don't create a debugging loop */
|
/* make sure we don't create a debugging loop */
|
||||||
|
@ -470,7 +470,7 @@ int debugger_detach( struct process *process, struct thread *debugger )
|
||||||
goto error; /* not currently debugged, or debugged by another debugger */
|
goto error; /* not currently debugged, or debugged by another debugger */
|
||||||
if (!debugger->debug_ctx ) goto error; /* should be a debugger */
|
if (!debugger->debug_ctx ) goto error; /* should be a debugger */
|
||||||
/* init should be done, otherwise wouldn't be attached */
|
/* init should be done, otherwise wouldn't be attached */
|
||||||
assert(!process->init_event);
|
assert(is_process_init_done(process));
|
||||||
|
|
||||||
suspend_process( process );
|
suspend_process( process );
|
||||||
/* send continue indication for all events */
|
/* send continue indication for all events */
|
||||||
|
|
104
server/process.c
104
server/process.c
|
@ -74,9 +74,12 @@ static const struct object_ops process_ops =
|
||||||
|
|
||||||
/* process startup info */
|
/* process startup info */
|
||||||
|
|
||||||
|
enum startup_state { STARTUP_IN_PROGRESS, STARTUP_DONE, STARTUP_ABORTED };
|
||||||
|
|
||||||
struct startup_info
|
struct startup_info
|
||||||
{
|
{
|
||||||
struct object obj; /* object header */
|
struct object obj; /* object header */
|
||||||
|
enum startup_state state; /* child process startup state */
|
||||||
int inherit_all; /* inherit all handles from parent */
|
int inherit_all; /* inherit all handles from parent */
|
||||||
int use_handles; /* use stdio handles */
|
int use_handles; /* use stdio handles */
|
||||||
int create_flags; /* creation flags */
|
int create_flags; /* creation flags */
|
||||||
|
@ -113,6 +116,16 @@ static const struct object_ops startup_info_ops =
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* set the state of the process startup info */
|
||||||
|
static void set_process_startup_state( struct process *process, enum startup_state state )
|
||||||
|
{
|
||||||
|
if (!process->startup_info) return;
|
||||||
|
process->startup_info->state = state;
|
||||||
|
wake_up( &process->startup_info->obj, 0 );
|
||||||
|
release_object( process->startup_info );
|
||||||
|
process->startup_info = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* set the console and stdio handles for a newly created process */
|
/* set the console and stdio handles for a newly created process */
|
||||||
static int set_process_console( struct process *process, struct thread *parent_thread,
|
static int set_process_console( struct process *process, struct thread *parent_thread,
|
||||||
struct startup_info *info, struct init_process_reply *reply )
|
struct startup_info *info, struct init_process_reply *reply )
|
||||||
|
@ -122,7 +135,7 @@ static int set_process_console( struct process *process, struct thread *parent_t
|
||||||
/* let the process init do the allocation */
|
/* let the process init do the allocation */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (parent_thread && !(process->create_flags & DETACHED_PROCESS))
|
else if (info && !(process->create_flags & DETACHED_PROCESS))
|
||||||
{
|
{
|
||||||
/* FIXME: some better error checking should be done...
|
/* FIXME: some better error checking should be done...
|
||||||
* like if hConOut and hConIn are console handles, then they should be on the same
|
* like if hConOut and hConIn are console handles, then they should be on the same
|
||||||
|
@ -131,7 +144,7 @@ static int set_process_console( struct process *process, struct thread *parent_t
|
||||||
inherit_console( parent_thread, process,
|
inherit_console( parent_thread, process,
|
||||||
(info->inherit_all || info->use_handles) ? info->hstdin : 0 );
|
(info->inherit_all || info->use_handles) ? info->hstdin : 0 );
|
||||||
}
|
}
|
||||||
if (parent_thread)
|
if (info)
|
||||||
{
|
{
|
||||||
if (!info->inherit_all && !info->use_handles)
|
if (!info->inherit_all && !info->use_handles)
|
||||||
{
|
{
|
||||||
|
@ -193,7 +206,7 @@ struct thread *create_process( int fd )
|
||||||
process->suspend = 0;
|
process->suspend = 0;
|
||||||
process->create_flags = 0;
|
process->create_flags = 0;
|
||||||
process->console = NULL;
|
process->console = NULL;
|
||||||
process->init_event = NULL;
|
process->startup_info = NULL;
|
||||||
process->idle_event = NULL;
|
process->idle_event = NULL;
|
||||||
process->queue = NULL;
|
process->queue = NULL;
|
||||||
process->atom_table = NULL;
|
process->atom_table = NULL;
|
||||||
|
@ -201,6 +214,7 @@ struct thread *create_process( int fd )
|
||||||
process->exe.next = NULL;
|
process->exe.next = NULL;
|
||||||
process->exe.prev = NULL;
|
process->exe.prev = NULL;
|
||||||
process->exe.file = NULL;
|
process->exe.file = NULL;
|
||||||
|
process->exe.base = NULL;
|
||||||
process->exe.dbg_offset = 0;
|
process->exe.dbg_offset = 0;
|
||||||
process->exe.dbg_size = 0;
|
process->exe.dbg_size = 0;
|
||||||
process->exe.namelen = 0;
|
process->exe.namelen = 0;
|
||||||
|
@ -210,9 +224,6 @@ struct thread *create_process( int fd )
|
||||||
if ((process->next = first_process) != NULL) process->next->prev = process;
|
if ((process->next = first_process) != NULL) process->next->prev = process;
|
||||||
first_process = process;
|
first_process = process;
|
||||||
|
|
||||||
/* create the init done event */
|
|
||||||
if (!(process->init_event = create_event( NULL, 0, 1, 0 ))) goto error;
|
|
||||||
|
|
||||||
/* create the main thread */
|
/* create the main thread */
|
||||||
if (pipe( request_pipe ) == -1)
|
if (pipe( request_pipe ) == -1)
|
||||||
{
|
{
|
||||||
|
@ -245,12 +256,7 @@ static struct startup_info *init_process( int ppid, struct init_process_reply *r
|
||||||
{
|
{
|
||||||
parent = parent_thread->process;
|
parent = parent_thread->process;
|
||||||
info = parent_thread->info;
|
info = parent_thread->info;
|
||||||
if (!info)
|
if (info && info->thread)
|
||||||
{
|
|
||||||
fatal_protocol_error( current, "init_process: parent but no info\n" );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (info->thread)
|
|
||||||
{
|
{
|
||||||
fatal_protocol_error( current, "init_process: called twice?\n" );
|
fatal_protocol_error( current, "init_process: called twice?\n" );
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -262,7 +268,7 @@ static struct startup_info *init_process( int ppid, struct init_process_reply *r
|
||||||
process->create_flags = info ? info->create_flags : 0;
|
process->create_flags = info ? info->create_flags : 0;
|
||||||
|
|
||||||
/* create the handle table */
|
/* create the handle table */
|
||||||
if (parent && info->inherit_all)
|
if (info && info->inherit_all)
|
||||||
process->handles = copy_handle_table( process, parent );
|
process->handles = copy_handle_table( process, parent );
|
||||||
else
|
else
|
||||||
process->handles = alloc_handle_table( process, 0 );
|
process->handles = alloc_handle_table( process, 0 );
|
||||||
|
@ -270,7 +276,7 @@ static struct startup_info *init_process( int ppid, struct init_process_reply *r
|
||||||
|
|
||||||
/* retrieve the main exe file */
|
/* retrieve the main exe file */
|
||||||
reply->exe_file = 0;
|
reply->exe_file = 0;
|
||||||
if (parent && info->exe_file)
|
if (info && info->exe_file)
|
||||||
{
|
{
|
||||||
process->exe.file = (struct file *)grab_object( info->exe_file );
|
process->exe.file = (struct file *)grab_object( info->exe_file );
|
||||||
if (!(reply->exe_file = alloc_handle( process, process->exe.file, GENERIC_READ, 0 )))
|
if (!(reply->exe_file = alloc_handle( process, process->exe.file, GENERIC_READ, 0 )))
|
||||||
|
@ -285,7 +291,7 @@ static struct startup_info *init_process( int ppid, struct init_process_reply *r
|
||||||
/* attach to the debugger if requested */
|
/* attach to the debugger if requested */
|
||||||
if (process->create_flags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
|
if (process->create_flags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
|
||||||
set_process_debugger( process, parent_thread );
|
set_process_debugger( process, parent_thread );
|
||||||
else if (parent && parent->debugger && !(parent->create_flags & DEBUG_ONLY_THIS_PROCESS))
|
else if (parent->debugger && !(parent->create_flags & DEBUG_ONLY_THIS_PROCESS))
|
||||||
set_process_debugger( process, parent->debugger );
|
set_process_debugger( process, parent->debugger );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,7 +303,6 @@ static struct startup_info *init_process( int ppid, struct init_process_reply *r
|
||||||
reply->info_size = info->data_size;
|
reply->info_size = info->data_size;
|
||||||
info->process = (struct process *)grab_object( process );
|
info->process = (struct process *)grab_object( process );
|
||||||
info->thread = (struct thread *)grab_object( current );
|
info->thread = (struct thread *)grab_object( current );
|
||||||
wake_up( &info->obj, 0 );
|
|
||||||
}
|
}
|
||||||
reply->create_flags = process->create_flags;
|
reply->create_flags = process->create_flags;
|
||||||
reply->server_start = server_start_ticks;
|
reply->server_start = server_start_ticks;
|
||||||
|
@ -312,12 +317,13 @@ static void process_destroy( struct object *obj )
|
||||||
|
|
||||||
/* we can't have a thread remaining */
|
/* we can't have a thread remaining */
|
||||||
assert( !process->thread_list );
|
assert( !process->thread_list );
|
||||||
|
|
||||||
|
set_process_startup_state( process, STARTUP_ABORTED );
|
||||||
if (process->console) release_object( process->console );
|
if (process->console) release_object( process->console );
|
||||||
if (process->parent) release_object( process->parent );
|
if (process->parent) release_object( process->parent );
|
||||||
if (process->next) process->next->prev = process->prev;
|
if (process->next) process->next->prev = process->prev;
|
||||||
if (process->prev) process->prev->next = process->next;
|
if (process->prev) process->prev->next = process->next;
|
||||||
else first_process = process->next;
|
else first_process = process->next;
|
||||||
if (process->init_event) release_object( process->init_event );
|
|
||||||
if (process->idle_event) release_object( process->idle_event );
|
if (process->idle_event) release_object( process->idle_event );
|
||||||
if (process->queue) release_object( process->queue );
|
if (process->queue) release_object( process->queue );
|
||||||
if (process->atom_table) release_object( process->atom_table );
|
if (process->atom_table) release_object( process->atom_table );
|
||||||
|
@ -371,17 +377,16 @@ static void startup_info_dump( struct object *obj, int verbose )
|
||||||
struct startup_info *info = (struct startup_info *)obj;
|
struct startup_info *info = (struct startup_info *)obj;
|
||||||
assert( obj->ops == &startup_info_ops );
|
assert( obj->ops == &startup_info_ops );
|
||||||
|
|
||||||
fprintf( stderr, "Startup info flags=%x in=%d out=%d err=%d\n",
|
fprintf( stderr, "Startup info flags=%x in=%d out=%d err=%d state=%d\n",
|
||||||
info->create_flags, info->hstdin, info->hstdout, info->hstderr );
|
info->create_flags, info->hstdin, info->hstdout, info->hstderr, info->state );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int startup_info_signaled( struct object *obj, struct thread *thread )
|
static int startup_info_signaled( struct object *obj, struct thread *thread )
|
||||||
{
|
{
|
||||||
struct startup_info *info = (struct startup_info *)obj;
|
struct startup_info *info = (struct startup_info *)obj;
|
||||||
return (info->thread != NULL);
|
return info->state != STARTUP_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* get a process from an id (and increment the refcount) */
|
/* get a process from an id (and increment the refcount) */
|
||||||
struct process *get_process_from_id( void *id )
|
struct process *get_process_from_id( void *id )
|
||||||
{
|
{
|
||||||
|
@ -490,6 +495,7 @@ static void process_killed( struct process *process )
|
||||||
if (dll->filename) free( dll->filename );
|
if (dll->filename) free( dll->filename );
|
||||||
free( dll );
|
free( dll );
|
||||||
}
|
}
|
||||||
|
set_process_startup_state( process, STARTUP_ABORTED );
|
||||||
if (process->exe.file) release_object( process->exe.file );
|
if (process->exe.file) release_object( process->exe.file );
|
||||||
process->exe.file = NULL;
|
process->exe.file = NULL;
|
||||||
wake_up( &process->obj, 0 );
|
wake_up( &process->obj, 0 );
|
||||||
|
@ -776,6 +782,7 @@ DECL_HANDLER(new_process)
|
||||||
|
|
||||||
/* build the startup info for a new process */
|
/* build the startup info for a new process */
|
||||||
if (!(info = alloc_object( &startup_info_ops, -1 ))) return;
|
if (!(info = alloc_object( &startup_info_ops, -1 ))) return;
|
||||||
|
info->state = STARTUP_IN_PROGRESS;
|
||||||
info->inherit_all = req->inherit_all;
|
info->inherit_all = req->inherit_all;
|
||||||
info->use_handles = req->use_handles;
|
info->use_handles = req->use_handles;
|
||||||
info->create_flags = req->create_flags;
|
info->create_flags = req->create_flags;
|
||||||
|
@ -807,8 +814,6 @@ DECL_HANDLER(get_new_process_info)
|
||||||
{
|
{
|
||||||
struct startup_info *info;
|
struct startup_info *info;
|
||||||
|
|
||||||
reply->event = 0;
|
|
||||||
|
|
||||||
if ((info = (struct startup_info *)get_handle_obj( current->process, req->info,
|
if ((info = (struct startup_info *)get_handle_obj( current->process, req->info,
|
||||||
0, &startup_info_ops )))
|
0, &startup_info_ops )))
|
||||||
{
|
{
|
||||||
|
@ -818,9 +823,7 @@ DECL_HANDLER(get_new_process_info)
|
||||||
PROCESS_ALL_ACCESS, req->pinherit );
|
PROCESS_ALL_ACCESS, req->pinherit );
|
||||||
reply->thandle = alloc_handle( current->process, info->thread,
|
reply->thandle = alloc_handle( current->process, info->thread,
|
||||||
THREAD_ALL_ACCESS, req->tinherit );
|
THREAD_ALL_ACCESS, req->tinherit );
|
||||||
if (info->process->init_event)
|
reply->success = (info->state == STARTUP_DONE);
|
||||||
reply->event = alloc_handle( current->process, info->process->init_event,
|
|
||||||
EVENT_ALL_ACCESS, 0 );
|
|
||||||
release_object( info );
|
release_object( info );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -829,6 +832,7 @@ DECL_HANDLER(get_new_process_info)
|
||||||
reply->tid = 0;
|
reply->tid = 0;
|
||||||
reply->phandle = 0;
|
reply->phandle = 0;
|
||||||
reply->thandle = 0;
|
reply->thandle = 0;
|
||||||
|
reply->success = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -837,19 +841,15 @@ DECL_HANDLER(get_startup_info)
|
||||||
{
|
{
|
||||||
struct startup_info *info;
|
struct startup_info *info;
|
||||||
|
|
||||||
if ((info = (struct startup_info *)get_handle_obj( current->process, req->info,
|
if ((info = current->process->startup_info))
|
||||||
0, &startup_info_ops )))
|
|
||||||
{
|
{
|
||||||
size_t size = info->data_size;
|
size_t size = info->data_size;
|
||||||
if (size > get_reply_max_size()) size = get_reply_max_size();
|
if (size > get_reply_max_size()) size = get_reply_max_size();
|
||||||
if (req->close)
|
|
||||||
{
|
/* we return the data directly without making a copy so this can only be called once */
|
||||||
set_reply_data_ptr( info->data, size );
|
set_reply_data_ptr( info->data, size );
|
||||||
info->data = NULL;
|
info->data = NULL;
|
||||||
close_handle( current->process, req->info, NULL );
|
info->data_size = 0;
|
||||||
}
|
|
||||||
else set_reply_data( info->data, size );
|
|
||||||
release_object( info );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -857,21 +857,19 @@ DECL_HANDLER(get_startup_info)
|
||||||
/* initialize a new process */
|
/* initialize a new process */
|
||||||
DECL_HANDLER(init_process)
|
DECL_HANDLER(init_process)
|
||||||
{
|
{
|
||||||
struct startup_info *info;
|
|
||||||
|
|
||||||
reply->info = 0;
|
|
||||||
reply->info_size = 0;
|
|
||||||
if (!current->unix_pid)
|
if (!current->unix_pid)
|
||||||
{
|
{
|
||||||
fatal_protocol_error( current, "init_process: init_thread not called yet\n" );
|
fatal_protocol_error( current, "init_process: init_thread not called yet\n" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
current->process->ldt_copy = req->ldt_copy;
|
if (current->process->startup_info)
|
||||||
if ((info = init_process( req->ppid, reply )))
|
|
||||||
{
|
{
|
||||||
reply->info = alloc_handle( current->process, info, 0, FALSE );
|
fatal_protocol_error( current, "init_process: called twice\n" );
|
||||||
release_object( info );
|
return;
|
||||||
}
|
}
|
||||||
|
reply->info_size = 0;
|
||||||
|
current->process->ldt_copy = req->ldt_copy;
|
||||||
|
current->process->startup_info = init_process( req->ppid, reply );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* signal the end of the process initialization */
|
/* signal the end of the process initialization */
|
||||||
|
@ -880,9 +878,14 @@ DECL_HANDLER(init_process_done)
|
||||||
struct file *file = NULL;
|
struct file *file = NULL;
|
||||||
struct process *process = current->process;
|
struct process *process = current->process;
|
||||||
|
|
||||||
if (!process->init_event)
|
if (is_process_init_done(process))
|
||||||
{
|
{
|
||||||
fatal_protocol_error( current, "init_process_done: no event\n" );
|
fatal_protocol_error( current, "init_process_done: called twice\n" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!req->module)
|
||||||
|
{
|
||||||
|
fatal_protocol_error( current, "init_process_done: module base address cannot be 0\n" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
process->exe.base = req->module;
|
process->exe.base = req->module;
|
||||||
|
@ -896,10 +899,9 @@ DECL_HANDLER(init_process_done)
|
||||||
if ((process->exe.namelen = get_req_data_size()))
|
if ((process->exe.namelen = get_req_data_size()))
|
||||||
process->exe.filename = memdup( get_req_data(), process->exe.namelen );
|
process->exe.filename = memdup( get_req_data(), process->exe.namelen );
|
||||||
|
|
||||||
generate_startup_debug_events( current->process, req->entry );
|
generate_startup_debug_events( process, req->entry );
|
||||||
set_event( process->init_event );
|
set_process_startup_state( process, STARTUP_DONE );
|
||||||
release_object( process->init_event );
|
|
||||||
process->init_event = NULL;
|
|
||||||
if (req->gui) process->idle_event = create_event( NULL, 0, 1, 0 );
|
if (req->gui) process->idle_event = create_event( NULL, 0, 1, 0 );
|
||||||
if (current->suspend + current->process->suspend > 0) stop_thread( current );
|
if (current->suspend + current->process->suspend > 0) stop_thread( current );
|
||||||
reply->debugged = (current->process->debugger != 0);
|
reply->debugged = (current->process->debugger != 0);
|
||||||
|
@ -1018,7 +1020,7 @@ DECL_HANDLER(load_dll)
|
||||||
dll->dbg_size = req->dbg_size;
|
dll->dbg_size = req->dbg_size;
|
||||||
dll->name = req->name;
|
dll->name = req->name;
|
||||||
/* only generate event if initialization is done */
|
/* only generate event if initialization is done */
|
||||||
if (!current->process->init_event)
|
if (is_process_init_done( current->process ))
|
||||||
generate_debug_event( current, LOAD_DLL_DEBUG_EVENT, dll );
|
generate_debug_event( current, LOAD_DLL_DEBUG_EVENT, dll );
|
||||||
}
|
}
|
||||||
if (file) release_object( file );
|
if (file) release_object( file );
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
struct msg_queue;
|
struct msg_queue;
|
||||||
struct atom_table;
|
struct atom_table;
|
||||||
|
struct startup_info;
|
||||||
|
|
||||||
/* process structures */
|
/* process structures */
|
||||||
|
|
||||||
|
@ -60,7 +61,7 @@ struct process
|
||||||
int suspend; /* global process suspend count */
|
int suspend; /* global process suspend count */
|
||||||
int create_flags; /* process creation flags */
|
int create_flags; /* process creation flags */
|
||||||
struct console_input*console; /* console input */
|
struct console_input*console; /* console input */
|
||||||
struct event *init_event; /* event for init done */
|
struct startup_info *startup_info; /* startup info while init is in progress */
|
||||||
struct event *idle_event; /* event for input idle */
|
struct event *idle_event; /* event for input idle */
|
||||||
struct msg_queue *queue; /* main message queue */
|
struct msg_queue *queue; /* main message queue */
|
||||||
struct atom_table *atom_table; /* pointer to local atom table */
|
struct atom_table *atom_table; /* pointer to local atom table */
|
||||||
|
@ -106,6 +107,7 @@ extern void detach_debugged_processes( struct thread *debugger );
|
||||||
extern struct process_snapshot *process_snap( int *count );
|
extern struct process_snapshot *process_snap( int *count );
|
||||||
extern struct module_snapshot *module_snap( struct process *process, int *count );
|
extern struct module_snapshot *module_snap( struct process *process, int *count );
|
||||||
|
|
||||||
static inline void *get_process_id( struct process *process ) { return process; }
|
inline static void *get_process_id( struct process *process ) { return process; }
|
||||||
|
inline static int is_process_init_done( struct process *process ) { return process->exe.base != 0; }
|
||||||
|
|
||||||
#endif /* __WINE_SERVER_PROCESS_H */
|
#endif /* __WINE_SERVER_PROCESS_H */
|
||||||
|
|
|
@ -220,7 +220,7 @@ typedef struct
|
||||||
handle_t phandle; /* process handle (in the current process) */
|
handle_t phandle; /* process handle (in the current process) */
|
||||||
void* tid; /* thread id */
|
void* tid; /* thread id */
|
||||||
handle_t thandle; /* thread handle (in the current process) */
|
handle_t thandle; /* thread handle (in the current process) */
|
||||||
handle_t event; /* event handle to signal startup */
|
int success; /* did the process start successfully? */
|
||||||
@END
|
@END
|
||||||
|
|
||||||
|
|
||||||
|
@ -248,7 +248,6 @@ typedef struct
|
||||||
@REPLY
|
@REPLY
|
||||||
int create_flags; /* creation flags */
|
int create_flags; /* creation flags */
|
||||||
unsigned int server_start; /* server start time (GetTickCount) */
|
unsigned int server_start; /* server start time (GetTickCount) */
|
||||||
handle_t info; /* handle to startup info */
|
|
||||||
size_t info_size; /* total size of startup info */
|
size_t info_size; /* total size of startup info */
|
||||||
handle_t exe_file; /* file handle for main exe */
|
handle_t exe_file; /* file handle for main exe */
|
||||||
handle_t hstdin; /* handle for stdin */
|
handle_t hstdin; /* handle for stdin */
|
||||||
|
@ -259,8 +258,6 @@ typedef struct
|
||||||
|
|
||||||
/* Retrieve the new process startup info */
|
/* Retrieve the new process startup info */
|
||||||
@REQ(get_startup_info)
|
@REQ(get_startup_info)
|
||||||
handle_t info; /* handle to startup info */
|
|
||||||
int close; /* should we close the handle at the same time? */
|
|
||||||
@REPLY
|
@REPLY
|
||||||
VARARG(info,startup_info); /* startup information */
|
VARARG(info,startup_info); /* startup information */
|
||||||
@END
|
@END
|
||||||
|
|
|
@ -177,7 +177,7 @@ void detach_thread( struct thread *thread, int sig )
|
||||||
void stop_thread( struct thread *thread )
|
void stop_thread( struct thread *thread )
|
||||||
{
|
{
|
||||||
/* can't stop a thread while initialisation is in progress */
|
/* can't stop a thread while initialisation is in progress */
|
||||||
if (!thread->unix_pid || thread->process->init_event) return;
|
if (!thread->unix_pid || !is_process_init_done(thread->process)) return;
|
||||||
/* first try to attach to it */
|
/* first try to attach to it */
|
||||||
if (!thread->attached)
|
if (!thread->attached)
|
||||||
if (attach_thread( thread )) return; /* this will have stopped it */
|
if (attach_thread( thread )) return; /* this will have stopped it */
|
||||||
|
@ -206,7 +206,7 @@ int suspend_for_ptrace( struct thread *thread )
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* can't stop a thread while initialisation is in progress */
|
/* can't stop a thread while initialisation is in progress */
|
||||||
if (!thread->unix_pid || thread->process->init_event) goto error;
|
if (!thread->unix_pid || !is_process_init_done(thread->process)) goto error;
|
||||||
thread->suspend++;
|
thread->suspend++;
|
||||||
if (attach_thread( thread )) return 1;
|
if (attach_thread( thread )) return 1;
|
||||||
thread->suspend--;
|
thread->suspend--;
|
||||||
|
|
|
@ -376,7 +376,7 @@ static void dump_get_new_process_info_reply( const struct get_new_process_info_r
|
||||||
fprintf( stderr, " phandle=%d,", req->phandle );
|
fprintf( stderr, " phandle=%d,", req->phandle );
|
||||||
fprintf( stderr, " tid=%p,", req->tid );
|
fprintf( stderr, " tid=%p,", req->tid );
|
||||||
fprintf( stderr, " thandle=%d,", req->thandle );
|
fprintf( stderr, " thandle=%d,", req->thandle );
|
||||||
fprintf( stderr, " event=%d", req->event );
|
fprintf( stderr, " success=%d", req->success );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_new_thread_request( const struct new_thread_request *req )
|
static void dump_new_thread_request( const struct new_thread_request *req )
|
||||||
|
@ -407,7 +407,6 @@ static void dump_init_process_reply( const struct init_process_reply *req )
|
||||||
{
|
{
|
||||||
fprintf( stderr, " create_flags=%d,", req->create_flags );
|
fprintf( stderr, " create_flags=%d,", req->create_flags );
|
||||||
fprintf( stderr, " server_start=%08x,", req->server_start );
|
fprintf( stderr, " server_start=%08x,", req->server_start );
|
||||||
fprintf( stderr, " info=%d,", req->info );
|
|
||||||
fprintf( stderr, " info_size=%d,", req->info_size );
|
fprintf( stderr, " info_size=%d,", req->info_size );
|
||||||
fprintf( stderr, " exe_file=%d,", req->exe_file );
|
fprintf( stderr, " exe_file=%d,", req->exe_file );
|
||||||
fprintf( stderr, " hstdin=%d,", req->hstdin );
|
fprintf( stderr, " hstdin=%d,", req->hstdin );
|
||||||
|
@ -417,8 +416,6 @@ static void dump_init_process_reply( const struct init_process_reply *req )
|
||||||
|
|
||||||
static void dump_get_startup_info_request( const struct get_startup_info_request *req )
|
static void dump_get_startup_info_request( const struct get_startup_info_request *req )
|
||||||
{
|
{
|
||||||
fprintf( stderr, " info=%d,", req->info );
|
|
||||||
fprintf( stderr, " close=%d", req->close );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_get_startup_info_reply( const struct get_startup_info_reply *req )
|
static void dump_get_startup_info_reply( const struct get_startup_info_reply *req )
|
||||||
|
|
Loading…
Reference in New Issue