Alexandre Julliard : server: Properly handle kill_thread recursion when killing a process.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Nov 10 05:44:03 CST 2006


Module: wine
Branch: master
Commit: 110a6fe5b65fd1b333f16d4878b9a6b2ad084557
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=110a6fe5b65fd1b333f16d4878b9a6b2ad084557

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Nov 10 12:18:54 2006 +0100

server: Properly handle kill_thread recursion when killing a process.

Spotted by Mike McCormack.

---

 server/process.c |   22 +++++++++++++++++-----
 1 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/server/process.c b/server/process.c
index cc4fd6f..b66e492 100644
--- a/server/process.c
+++ b/server/process.c
@@ -515,15 +515,25 @@ static void process_unload_dll( struct p
 /* terminate a process with the given exit code */
 static void terminate_process( struct process *process, struct thread *skip, int exit_code )
 {
-    struct list *ptr, *next;
+    struct list *ptr;
+
+    if (skip)  /* move it to the end of the list */
+    {
+        assert( skip->state != TERMINATED );
+        list_remove( &skip->proc_entry );
+        list_add_tail( &process->thread_list, &skip->proc_entry );
+    }
 
-    LIST_FOR_EACH_SAFE( ptr, next, &process->thread_list )
+    grab_object( process );  /* make sure it doesn't get freed when threads die */
+    while ((ptr = list_head( &process->thread_list )))
     {
         struct thread *thread = LIST_ENTRY( ptr, struct thread, proc_entry );
 
         if (exit_code) thread->exit_code = exit_code;
-        if (thread != skip) kill_thread( thread, 1 );
+        if (thread == skip) break;
+        kill_thread( thread, 1 );
     }
+    release_object( process );
 }
 
 /* kill all processes */
@@ -657,13 +667,15 @@ void kill_process( struct process *proce
     if (violent_death) terminate_process( process, NULL, 1 );
     else
     {
-        struct list *ptr, *next;
+        struct list *ptr;
 
-        LIST_FOR_EACH_SAFE( ptr, next, &process->thread_list )
+        grab_object( process );  /* make sure it doesn't get freed when threads die */
+        while ((ptr = list_head( &process->thread_list )))
         {
             struct thread *thread = LIST_ENTRY( ptr, struct thread, proc_entry );
             kill_thread( thread, 0 );
         }
+        release_object( process );
     }
 }
 




More information about the wine-cvs mailing list