Alexandre Julliard : server: Check for the need to suspend a thread again once it leaves an exception or suspend block .

Alexandre Julliard julliard at winehq.org
Fri May 6 13:43:56 CDT 2011


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri May  6 12:43:16 2011 +0200

server: Check for the need to suspend a thread again once it leaves an exception or suspend block.

---

 server/debugger.c |    7 ++++++-
 server/process.c  |    2 +-
 server/thread.c   |   14 ++++++++++++--
 server/thread.h   |    1 +
 4 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/server/debugger.c b/server/debugger.c
index 2ee6f6d..d8a390e 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -308,7 +308,11 @@ static void debug_event_destroy( struct object *obj )
             break;
         }
     }
-    if (event->sender->context == &event->context) event->sender->context = NULL;
+    if (event->sender->context == &event->context)
+    {
+        event->sender->context = NULL;
+        stop_thread_if_suspended( event->sender );
+    }
     release_object( event->sender );
     release_object( event->debugger );
 }
@@ -680,6 +684,7 @@ DECL_HANDLER(get_exception_status)
                 data_size_t size = min( sizeof(context_t), get_reply_max_size() );
                 set_reply_data( &event->context, size );
                 current->context = NULL;
+                stop_thread_if_suspended( current );
             }
             set_error( event->status );
         }
diff --git a/server/process.c b/server/process.c
index 797b4cf..f5430c8 100644
--- a/server/process.c
+++ b/server/process.c
@@ -1045,7 +1045,7 @@ DECL_HANDLER(init_process_done)
     set_process_startup_state( process, STARTUP_DONE );
 
     if (req->gui) process->idle_event = create_event( NULL, NULL, 0, 1, 0, NULL );
-    if (current->suspend + process->suspend > 0) stop_thread( current );
+    stop_thread_if_suspended( current );
     if (process->debugger) set_process_debug_flag( process, 1 );
 }
 
diff --git a/server/thread.c b/server/thread.c
index 9e56b1b..4388847 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -491,6 +491,12 @@ void stop_thread( struct thread *thread )
     if (is_process_init_done(thread->process)) send_thread_signal( thread, SIGUSR1 );
 }
 
+/* stop a thread if it's supposed to be suspended */
+void stop_thread_if_suspended( struct thread *thread )
+{
+    if (thread->suspend + thread->process->suspend > 0) stop_thread( thread );
+}
+
 /* suspend a thread */
 static int suspend_thread( struct thread *thread )
 {
@@ -1182,7 +1188,7 @@ DECL_HANDLER(init_thread)
         }
         if (process->unix_pid != current->unix_pid)
             process->unix_pid = -1;  /* can happen with linuxthreads */
-        if (current->suspend + process->suspend > 0) stop_thread( current );
+        stop_thread_if_suspended( current );
         generate_debug_event( current, CREATE_THREAD_DEBUG_EVENT, &req->entry );
         set_thread_affinity( current, current->affinity );
     }
@@ -1556,7 +1562,11 @@ DECL_HANDLER(get_suspend_context)
     if (current->suspend_context)
     {
         set_reply_data_ptr( current->suspend_context, sizeof(context_t) );
-        if (current->context == current->suspend_context) current->context = NULL;
+        if (current->context == current->suspend_context)
+        {
+            current->context = NULL;
+            stop_thread_if_suspended( current );
+        }
         current->suspend_context = NULL;
     }
     else set_error( STATUS_INVALID_PARAMETER );  /* not suspended, shouldn't happen */
diff --git a/server/thread.h b/server/thread.h
index 1e95732..1c4a74a 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -106,6 +106,7 @@ extern struct thread *get_thread_from_handle( obj_handle_t handle, unsigned int
 extern struct thread *get_thread_from_tid( int tid );
 extern struct thread *get_thread_from_pid( int pid );
 extern void stop_thread( struct thread *thread );
+extern void stop_thread_if_suspended( struct thread *thread );
 extern int wake_thread( struct thread *thread );
 extern int add_queue( struct object *obj, struct wait_queue_entry *entry );
 extern void remove_queue( struct object *obj, struct wait_queue_entry *entry );




More information about the wine-cvs mailing list