Made handle table a separate object.
Global handle table is no longer bound to a process.
Removed special handling of the initial process.
diff --git a/server/process.c b/server/process.c
index f7617f0..125b089 100644
--- a/server/process.c
+++ b/server/process.c
@@ -24,8 +24,7 @@
/* process structure */
-static struct process initial_process;
-static struct process *first_process = &initial_process;
+static struct process *first_process;
static int running_processes;
/* process operations */
@@ -49,16 +48,20 @@
};
-/* initialization of a process structure */
-static void init_process( struct process *process )
+/* create a new process */
+static struct process *create_process( struct process *parent,
+ struct new_process_request *req, const char *cmd_line )
{
- init_object( &process->obj, &process_ops, NULL );
+ struct process *process;
+
+ if (!(process = alloc_object( sizeof(*process), &process_ops, NULL ))) return NULL;
process->next = NULL;
process->prev = NULL;
process->thread_list = NULL;
process->debug_next = NULL;
process->debug_prev = NULL;
process->debugger = NULL;
+ process->handles = NULL;
process->exit_code = 0x103; /* STILL_ACTIVE */
process->running_threads = 0;
process->priority = NORMAL_PRIORITY_CLASS;
@@ -68,47 +71,15 @@
process->console_out = NULL;
process->info = NULL;
gettimeofday( &process->start_time, NULL );
+
+ if (req->inherit_all)
+ process->handles = copy_handle_table( process, parent );
+ else
+ process->handles = alloc_handle_table( process, 0 );
+ if (!process->handles) goto error;
+
/* alloc a handle for the process itself */
alloc_handle( process, process, PROCESS_ALL_ACCESS, 0 );
-}
-
-/* create the initial process */
-struct process *create_initial_process(void)
-{
- struct new_process_request *info;
-
- copy_handle_table( &initial_process, NULL );
- init_process( &initial_process );
-
- if (!alloc_console( &initial_process )) return NULL;
- if (!(info = mem_alloc( sizeof(*info) ))) return NULL;
- info->start_flags = STARTF_USESTDHANDLES;
- info->hstdin = alloc_handle( &initial_process, initial_process.console_in,
- GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 );
- info->hstdout = alloc_handle( &initial_process, initial_process.console_out,
- GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 );
- info->hstderr = alloc_handle( &initial_process, initial_process.console_out,
- GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 );
- info->env_ptr = NULL;
- initial_process.info = info;
- grab_object( &initial_process ); /* so that we never free it */
- return &initial_process;
-
-}
-
-/* create a new process */
-static struct process *create_process( struct new_process_request *req, const char *cmd_line )
-{
- struct process *process = NULL;
- struct process *parent = current->process;
-
- if (!(process = mem_alloc( sizeof(*process) ))) return NULL;
- if (!copy_handle_table( process, req->inherit_all ? parent : NULL ))
- {
- free( process );
- return NULL;
- }
- init_process( process );
if (!(process->info = mem_alloc( sizeof(*process->info) + strlen(cmd_line) + 1 ))) goto error;
memcpy( process->info, req, sizeof(*req) );
@@ -138,33 +109,60 @@
/* attach to the debugger if requested */
if (req->create_flags & DEBUG_PROCESS)
debugger_attach( process, current );
- else if (parent->debugger && !(req->create_flags & DEBUG_ONLY_THIS_PROCESS))
+ else if (parent && parent->debugger && !(req->create_flags & DEBUG_ONLY_THIS_PROCESS))
debugger_attach( process, parent->debugger );
- process->next = first_process;
- first_process->prev = process;
+ if ((process->next = first_process) != NULL) process->next->prev = process;
first_process = process;
return process;
error:
+ free_console( process );
+ if (process->info) free( process->info );
+ if (process->handles) release_object( process->handles );
release_object( process );
return NULL;
}
+/* create the initial process */
+struct process *create_initial_process(void)
+{
+ struct process *process;
+ struct new_process_request req;
+
+ req.inherit = 0;
+ req.inherit_all = 0;
+ req.create_flags = CREATE_NEW_CONSOLE;
+ req.start_flags = STARTF_USESTDHANDLES;
+ req.hstdin = -1;
+ req.hstdout = -1;
+ req.hstderr = -1;
+ req.cmd_show = 0;
+ req.env_ptr = NULL;
+ if ((process = create_process( NULL, &req, "" )))
+ {
+ process->info->hstdin = alloc_handle( process, process->console_in,
+ GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 );
+ process->info->hstdout = alloc_handle( process, process->console_out,
+ GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 );
+ process->info->hstderr = alloc_handle( process, process->console_out,
+ GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 );
+ release_object( process );
+ }
+ return process;
+}
+
/* destroy a process when its refcount is 0 */
static void process_destroy( struct object *obj )
{
struct process *process = (struct process *)obj;
assert( obj->ops == &process_ops );
- assert( process != &initial_process );
/* we can't have a thread remaining */
assert( !process->thread_list );
if (process->next) process->next->prev = process->prev;
if (process->prev) process->prev->next = process->next;
else first_process = process->next;
- free_console( process );
- free_handles( process );
if (process->info) free( process->info );
if (debug_level) memset( process, 0xbb, sizeof(process) ); /* catch errors */
free( process );
@@ -176,7 +174,9 @@
struct process *process = (struct process *)obj;
assert( obj->ops == &process_ops );
- printf( "Process next=%p prev=%p\n", process->next, process->prev );
+ fprintf( stderr, "Process next=%p prev=%p console=%p/%p handles=%p\n",
+ process->next, process->prev, process->console_in, process->console_out,
+ process->handles );
}
static int process_signaled( struct object *obj, struct thread *thread )
@@ -209,8 +209,15 @@
assert( !process->thread_list );
process->exit_code = exit_code;
gettimeofday( &process->end_time, NULL );
+ release_object( process->handles );
+ process->handles = NULL;
+ free_console( process );
wake_up( &process->obj, 0 );
- free_handles( process );
+ if (!--running_processes)
+ {
+ /* last process died, close global handles */
+ close_global_handles();
+ }
}
/* add a thread to a process running threads list */
@@ -237,7 +244,6 @@
if (!--process->running_threads)
{
/* we have removed the last running thread, exit the process */
- running_processes--;
process_killed( process, thread->exit_code );
}
release_object( thread );
@@ -366,7 +372,7 @@
char *cmd_line = (char *)data;
CHECK_STRING( "new_process", cmd_line, len );
- if ((process = create_process( req, cmd_line )))
+ if ((process = create_process( current->process, req, cmd_line )))
{
reply.pid = process;
reply.handle = alloc_handle( current->process, process,