Convert the per-process thread list to a standard list.
diff --git a/server/console.c b/server/console.c
index 6f54f66..b51f56d 100644
--- a/server/console.c
+++ b/server/console.c
@@ -78,7 +78,6 @@
{
struct object obj; /* object header */
struct list entry; /* entry in list of all screen buffers */
- struct screen_buffer *prev;
struct console_input *input; /* associated console input */
int mode; /* output mode */
int cursor_size; /* size of cursor (percentage filled) */
@@ -400,7 +399,7 @@
{
/* find a suitable thread to signal */
struct thread *thread;
- for (thread = process->thread_list; thread; thread = thread->proc_next)
+ LIST_FOR_EACH_ENTRY( thread, &process->thread_list, struct thread, proc_entry )
{
if (send_thread_signal( thread, csi->signal )) break;
}
diff --git a/server/debugger.c b/server/debugger.c
index 1efea77..3ea9f93 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -406,7 +406,7 @@
if (process->debugger) goto error; /* already being debugged */
if (!is_process_init_done( process )) goto error; /* still starting up */
- if (!process->thread_list) goto error; /* no thread running in the process */
+ if (list_empty( &process->thread_list )) goto error; /* no thread running in the process */
/* make sure we don't create a debugging loop */
for (thread = debugger; thread; thread = thread->process->debugger)
@@ -489,19 +489,23 @@
void generate_startup_debug_events( struct process *process, void *entry )
{
struct process_dll *dll;
- struct thread *thread = process->thread_list;
+ struct thread *thread, *first_thread = get_process_first_thread( process );
/* generate creation events */
- generate_debug_event( thread, CREATE_PROCESS_DEBUG_EVENT, entry );
- while ((thread = thread->proc_next))
- generate_debug_event( thread, CREATE_THREAD_DEBUG_EVENT, NULL );
+ LIST_FOR_EACH_ENTRY( thread, &process->thread_list, struct thread, proc_entry )
+ {
+ if (thread == first_thread)
+ generate_debug_event( thread, CREATE_PROCESS_DEBUG_EVENT, entry );
+ else
+ generate_debug_event( thread, CREATE_THREAD_DEBUG_EVENT, NULL );
+ }
/* generate dll events (in loading order, i.e. reverse list order) */
dll = &process->exe;
while (dll->next) dll = dll->next;
while (dll != &process->exe)
{
- generate_debug_event( process->thread_list, LOAD_DLL_DEBUG_EVENT, dll );
+ generate_debug_event( first_thread, LOAD_DLL_DEBUG_EVENT, dll );
dll = dll->prev;
}
}
@@ -603,6 +607,7 @@
else if (debugger_attach( process, current ))
{
struct debug_event_exception data;
+ struct thread *thread = get_process_first_thread( process );
generate_startup_debug_events( process, NULL );
resume_process( process );
@@ -610,10 +615,10 @@
data.record.ExceptionCode = EXCEPTION_BREAKPOINT;
data.record.ExceptionFlags = EXCEPTION_CONTINUABLE;
data.record.ExceptionRecord = NULL;
- data.record.ExceptionAddress = get_thread_ip( process->thread_list );
+ data.record.ExceptionAddress = get_thread_ip( thread );
data.record.NumberParameters = 0;
data.first = 1;
- generate_debug_event( process->thread_list, EXCEPTION_DEBUG_EVENT, &data );
+ generate_debug_event( thread, EXCEPTION_DEBUG_EVENT, &data );
}
release_object( process );
}
@@ -695,13 +700,15 @@
{
/* find a suitable thread to signal */
struct thread *thread;
- for (thread = process->thread_list; thread; thread = thread->proc_next)
+ LIST_FOR_EACH_ENTRY( thread, &process->thread_list, struct thread, proc_entry )
{
- if (send_thread_signal( thread, SIGTRAP )) break;
+ if (send_thread_signal( thread, SIGTRAP )) goto done;
}
- if (!thread) set_error( STATUS_ACCESS_DENIED );
+ set_error( STATUS_ACCESS_DENIED );
}
else reply->self = 1;
+
+done:
release_object( process );
}
diff --git a/server/process.c b/server/process.c
index 779f8fb..4b8d6f2 100644
--- a/server/process.c
+++ b/server/process.c
@@ -192,6 +192,14 @@
return ptid_entries[id - PTID_OFFSET].ptr;
}
+/* return the main thread of the process */
+struct thread *get_process_first_thread( struct process *process )
+{
+ struct list *ptr = list_head( &process->thread_list );
+ if (!ptr) return NULL;
+ return LIST_ENTRY( ptr, struct thread, proc_entry );
+}
+
/* set the state of the process startup info */
static void set_process_startup_state( struct process *process, enum startup_state state )
{
@@ -250,7 +258,6 @@
if (!(process = alloc_object( &process_ops ))) goto error;
process->parent = NULL;
- process->thread_list = NULL;
process->debugger = NULL;
process->handles = NULL;
process->msg_fd = NULL;
@@ -277,6 +284,7 @@
process->exe.filename = NULL;
process->group_id = 0;
process->token = create_admin_token();
+ list_init( &process->thread_list );
list_init( &process->locks );
list_init( &process->classes );
@@ -400,7 +408,7 @@
assert( obj->ops == &process_ops );
/* we can't have a thread remaining */
- assert( !process->thread_list );
+ assert( list_empty( &process->thread_list ));
set_process_startup_state( process, STARTUP_ABORTED );
if (process->console) release_object( process->console );
@@ -576,7 +584,7 @@
/* a process has been killed (i.e. its last thread died) */
static void process_killed( struct process *process )
{
- assert( !process->thread_list );
+ assert( list_empty( &process->thread_list ));
gettimeofday( &process->end_time, NULL );
if (process->handles) release_object( process->handles );
process->handles = NULL;
@@ -603,10 +611,7 @@
/* add a thread to a process running threads list */
void add_process_thread( struct process *process, struct thread *thread )
{
- thread->proc_next = process->thread_list;
- thread->proc_prev = NULL;
- if (thread->proc_next) thread->proc_next->proc_prev = thread;
- process->thread_list = thread;
+ list_add_head( &process->thread_list, &thread->proc_entry );
if (!process->running_threads++) running_processes++;
grab_object( thread );
}
@@ -615,11 +620,9 @@
void remove_process_thread( struct process *process, struct thread *thread )
{
assert( process->running_threads > 0 );
- assert( process->thread_list );
+ assert( !list_empty( &process->thread_list ));
- if (thread->proc_next) thread->proc_next->proc_prev = thread->proc_prev;
- if (thread->proc_prev) thread->proc_prev->proc_next = thread->proc_next;
- else process->thread_list = thread->proc_next;
+ list_remove( &thread->proc_entry );
if (!--process->running_threads)
{
@@ -637,12 +640,12 @@
{
if (!process->suspend++)
{
- struct thread *thread = process->thread_list;
- while (thread)
+ struct list *ptr, *next;
+
+ LIST_FOR_EACH_SAFE( ptr, next, &process->thread_list )
{
- struct thread *next = thread->proc_next;
+ struct thread *thread = LIST_ENTRY( ptr, struct thread, proc_entry );
if (!thread->suspend) stop_thread( thread );
- thread = next;
}
}
}
@@ -653,12 +656,12 @@
assert (process->suspend > 0);
if (!--process->suspend)
{
- struct thread *thread = process->thread_list;
- while (thread)
+ struct list *ptr, *next;
+
+ LIST_FOR_EACH_SAFE( ptr, next, &process->thread_list )
{
- struct thread *next = thread->proc_next;
+ struct thread *thread = LIST_ENTRY( ptr, struct thread, proc_entry );
if (!thread->suspend) wake_thread( thread );
- thread = next;
}
}
}
@@ -666,14 +669,14 @@
/* kill a process on the spot */
void kill_process( struct process *process, struct thread *skip, int exit_code )
{
- struct thread *thread = process->thread_list;
+ struct list *ptr, *next;
- while (thread)
+ LIST_FOR_EACH_SAFE( ptr, next, &process->thread_list )
{
- struct thread *next = thread->proc_next;
+ struct thread *thread = LIST_ENTRY( ptr, struct thread, proc_entry );
+
thread->exit_code = exit_code;
if (thread != skip) kill_thread( thread, 1 );
- thread = next;
}
}
@@ -728,7 +731,7 @@
/* len is the total size (in ints) */
static int read_process_memory( struct process *process, const int *addr, size_t len, int *dest )
{
- struct thread *thread = process->thread_list;
+ struct thread *thread = get_process_first_thread( process );
assert( !((unsigned int)addr % sizeof(int)) ); /* address must be aligned */
@@ -771,7 +774,7 @@
static int write_process_memory( struct process *process, int *addr, size_t len,
unsigned int first_mask, unsigned int last_mask, const int *src )
{
- struct thread *thread = process->thread_list;
+ struct thread *thread = get_process_first_thread( process );
int ret = 0;
assert( !((unsigned int)addr % sizeof(int) )); /* address must be aligned */
diff --git a/server/process.h b/server/process.h
index 00d935e..dae1aa8 100644
--- a/server/process.h
+++ b/server/process.h
@@ -52,7 +52,7 @@
struct object obj; /* object header */
struct list entry; /* entry in system-wide process list */
struct process *parent; /* parent process */
- struct thread *thread_list; /* head of the thread list */
+ struct list thread_list; /* thread list */
struct thread *debugger; /* thread debugging this process */
struct handle_table *handles; /* handle entries */
struct fd *msg_fd; /* fd for sendmsg/recvmsg */
@@ -103,6 +103,7 @@
extern void free_ptid( unsigned int id );
extern void *get_ptid_entry( unsigned int id );
extern struct thread *create_process( int fd );
+extern struct thread *get_process_first_thread( struct process *process );
extern struct process *get_process_from_id( process_id_t id );
extern struct process *get_process_from_handle( obj_handle_t handle, unsigned int access );
extern int process_set_debugger( struct process *process, struct thread *thread );
diff --git a/server/ptrace.c b/server/ptrace.c
index 42a0d3a..c1a8cb7 100644
--- a/server/ptrace.c
+++ b/server/ptrace.c
@@ -228,12 +228,13 @@
struct thread *thread;
int ret = 1;
- if (!process->thread_list) /* need at least one running thread */
+ if (list_empty( &process->thread_list )) /* need at least one running thread */
{
set_error( STATUS_ACCESS_DENIED );
return 0;
}
- for (thread = process->thread_list; thread; thread = thread->proc_next)
+
+ LIST_FOR_EACH_ENTRY( thread, &process->thread_list, struct thread, proc_entry )
{
if (thread->attached) continue;
if (suspend_for_ptrace( thread )) resume_after_ptrace( thread );
@@ -247,7 +248,7 @@
{
struct thread *thread;
- for (thread = process->thread_list; thread; thread = thread->proc_next)
+ LIST_FOR_EACH_ENTRY( thread, &process->thread_list, struct thread, proc_entry )
{
if (thread->attached) detach_thread( thread, 0 );
}
diff --git a/server/request.c b/server/request.c
index 1292dd8..a035e16 100644
--- a/server/request.c
+++ b/server/request.c
@@ -362,7 +362,7 @@
struct thread *thread;
if (data.tid) thread = get_thread_from_id( data.tid );
- else thread = (struct thread *)grab_object( process->thread_list );
+ else thread = (struct thread *)grab_object( get_process_first_thread( process ));
if (!thread || thread->process != process || thread->state == TERMINATED)
{
diff --git a/server/thread.h b/server/thread.h
index a7c544b..d13199b 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -51,8 +51,7 @@
{
struct object obj; /* object header */
struct list entry; /* entry in system-wide thread list */
- struct thread *proc_next; /* per-process thread list */
- struct thread *proc_prev;
+ struct list proc_entry; /* entry in per-process thread list */
struct process *process;
thread_id_t id; /* thread id */
struct list mutex_list; /* list of currently owned mutexes */