Module: wine Branch: master Commit: 2520e387a190439dfcb1809f1e5819fab08773c9 URL: http://source.winehq.org/git/wine.git/?a=commit;h=2520e387a190439dfcb1809f1e...
Author: Alexandre Julliard julliard@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 );