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