server: Allow suspended threads to run system APCs.
This commit is contained in:
parent
443a5dbd80
commit
2520e387a1
|
@ -161,7 +161,7 @@ void wait_suspend( CONTEXT *context )
|
||||||
|
|
||||||
/* wait with 0 timeout, will only return once the thread is no longer suspended */
|
/* wait with 0 timeout, will only return once the thread is no longer suspended */
|
||||||
timeout.QuadPart = 0;
|
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 */
|
/* retrieve the new context */
|
||||||
SERVER_START_REQ( get_thread_context )
|
SERVER_START_REQ( get_thread_context )
|
||||||
|
|
|
@ -470,8 +470,13 @@ static int check_wait( struct thread *thread )
|
||||||
struct thread_wait *wait = thread->wait;
|
struct thread_wait *wait = thread->wait;
|
||||||
struct wait_queue_entry *entry = wait->queues;
|
struct wait_queue_entry *entry = wait->queues;
|
||||||
|
|
||||||
/* Suspended threads may not acquire locks */
|
/* Suspended threads may not acquire locks, but they can run system APCs */
|
||||||
if (thread->process->suspend + thread->suspend > 0) return -1;
|
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 );
|
assert( wait );
|
||||||
if (wait->flags & SELECT_ALL)
|
if (wait->flags & SELECT_ALL)
|
||||||
|
@ -1077,6 +1082,7 @@ DECL_HANDLER(queue_apc)
|
||||||
DECL_HANDLER(get_apc)
|
DECL_HANDLER(get_apc)
|
||||||
{
|
{
|
||||||
struct thread_apc *apc;
|
struct thread_apc *apc;
|
||||||
|
int system_only = !req->alertable;
|
||||||
|
|
||||||
if (req->prev)
|
if (req->prev)
|
||||||
{
|
{
|
||||||
|
@ -1088,9 +1094,11 @@ DECL_HANDLER(get_apc)
|
||||||
release_object( apc );
|
release_object( apc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (current->suspend + current->process->suspend > 0) system_only = 1;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (!(apc = thread_dequeue_apc( current, !req->alertable )))
|
if (!(apc = thread_dequeue_apc( current, system_only )))
|
||||||
{
|
{
|
||||||
/* no more APCs */
|
/* no more APCs */
|
||||||
set_error( STATUS_PENDING );
|
set_error( STATUS_PENDING );
|
||||||
|
|
Loading…
Reference in New Issue