Alexandre Julliard : server: Allow suspended threads to run system APCs.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Jan 10 15:47:06 CST 2007


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Jan 10 21:55:23 2007 +0100

server: Allow suspended threads to run system APCs.

---

 dlls/ntdll/exception.c |    2 +-
 server/thread.c        |   14 +++++++++++---
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/dlls/ntdll/exception.c b/dlls/ntdll/exception.c
index 36d462f..a2f16c5 100644
--- a/dlls/ntdll/exception.c
+++ b/dlls/ntdll/exception.c
@@ -161,7 +161,7 @@ void wait_suspend( CONTEXT *context )
 
     /* wait with 0 timeout, will only return once the thread is no longer suspended */
     timeout.QuadPart = 0;
-    NTDLL_wait_for_multiple_objects( 0, NULL, 0, &timeout, 0 );
+    NTDLL_wait_for_multiple_objects( 0, NULL, SELECT_INTERRUPTIBLE, &timeout, 0 );
 
     /* retrieve the new context */
     SERVER_START_REQ( get_thread_context )
diff --git a/server/thread.c b/server/thread.c
index 476ee32..b8ee6fc 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -470,8 +470,13 @@ static int check_wait( struct thread *th
     struct thread_wait *wait = thread->wait;
     struct wait_queue_entry *entry = wait->queues;
 
-    /* Suspended threads may not acquire locks */
-    if (thread->process->suspend + thread->suspend > 0) return -1;
+    /* Suspended threads may not acquire locks, but they can run system APCs */
+    if (thread->process->suspend + thread->suspend > 0)
+    {
+        if ((wait->flags & SELECT_INTERRUPTIBLE) && !list_empty( &thread->system_apc ))
+            return STATUS_USER_APC;
+        return -1;
+    }
 
     assert( wait );
     if (wait->flags & SELECT_ALL)
@@ -1077,6 +1082,7 @@ DECL_HANDLER(queue_apc)
 DECL_HANDLER(get_apc)
 {
     struct thread_apc *apc;
+    int system_only = !req->alertable;
 
     if (req->prev)
     {
@@ -1088,9 +1094,11 @@ DECL_HANDLER(get_apc)
         release_object( apc );
     }
 
+    if (current->suspend + current->process->suspend > 0) system_only = 1;
+
     for (;;)
     {
-        if (!(apc = thread_dequeue_apc( current, !req->alertable )))
+        if (!(apc = thread_dequeue_apc( current, system_only )))
         {
             /* no more APCs */
             set_error( STATUS_PENDING );




More information about the wine-cvs mailing list