mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Fix APC problems. Thanks to Arty for finding this. This makes vncviewer work
svn path=/trunk/; revision=13484
This commit is contained in:
parent
73f1d215e0
commit
ef53ccc2a8
1 changed files with 29 additions and 36 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* $Id:$
|
/* $Id$
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS project
|
* PROJECT: ReactOS project
|
||||||
|
@ -489,6 +489,7 @@ KeWaitForMultipleObjects(ULONG Count,
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
BOOLEAN Abandoned;
|
BOOLEAN Abandoned;
|
||||||
|
NTSTATUS WaitStatus;
|
||||||
|
|
||||||
DPRINT("Entering KeWaitForMultipleObjects(Count %lu Object[] %p) "
|
DPRINT("Entering KeWaitForMultipleObjects(Count %lu Object[] %p) "
|
||||||
"PsGetCurrentThread() %x\n", Count, Object, PsGetCurrentThread());
|
"PsGetCurrentThread() %x\n", Count, Object, PsGetCurrentThread());
|
||||||
|
@ -540,39 +541,31 @@ KeWaitForMultipleObjects(ULONG Count,
|
||||||
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Alertability 101
|
/* Get the current Wait Status */
|
||||||
* ----------------
|
WaitStatus = CurrentThread->WaitStatus;
|
||||||
* A Wait can either be Alertable, or Non-Alertable.
|
|
||||||
* An Alertable Wait means that APCs can "Wake" the Thread, also called UnWaiting
|
|
||||||
* If an APC is Pending however, we must refuse an Alertable Wait. Such a wait would
|
|
||||||
* be pointless since an APC is just about to be delivered.
|
|
||||||
*
|
|
||||||
* There are many ways to check if it's safe to be alertable, and these are the ones
|
|
||||||
* that I could think of:
|
|
||||||
* - The Thread is already Alerted. So someone beat us to the punch and we bail out.
|
|
||||||
* - The Thread is Waiting in User-Mode, the APC Queue is not-empty.
|
|
||||||
* It's defintely clear that we have incoming APCs, so we need to bail out and let the system
|
|
||||||
* know that there are Pending User APCs (so they can be Delivered and maybe we can try again)
|
|
||||||
*
|
|
||||||
* Furthermore, wether or not we want to be Alertable, if the Thread is waiting in User-Mode, and there
|
|
||||||
* are Pending User APCs, we should bail out, since APCs will be delivered any second.
|
|
||||||
*/
|
|
||||||
if (Alertable) {
|
if (Alertable) {
|
||||||
|
|
||||||
|
/* If the Thread is Alerted, set the Wait Status accordingly */
|
||||||
if (CurrentThread->Alerted[(int)WaitMode]) {
|
if (CurrentThread->Alerted[(int)WaitMode]) {
|
||||||
|
|
||||||
CurrentThread->Alerted[(int)WaitMode] = FALSE;
|
CurrentThread->Alerted[(int)WaitMode] = FALSE;
|
||||||
DPRINT("Alertability failed\n");
|
DPRINT("Thread was Alerted\n");
|
||||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
WaitStatus = STATUS_ALERTED;
|
||||||
return (STATUS_ALERTED);
|
|
||||||
} else if ((!IsListEmpty(&CurrentThread->ApcState.ApcListHead[UserMode])) && (WaitMode == UserMode)) {
|
/* If there are User APCs Pending, then we can't really be alertable */
|
||||||
DPRINT1("Alertability failed\n");
|
} else if ((!IsListEmpty(&CurrentThread->ApcState.ApcListHead[UserMode])) &&
|
||||||
|
(WaitMode == UserMode)) {
|
||||||
|
|
||||||
|
DPRINT1("APCs are Pending\n");
|
||||||
CurrentThread->ApcState.UserApcPending = TRUE;
|
CurrentThread->ApcState.UserApcPending = TRUE;
|
||||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
WaitStatus = STATUS_USER_APC;
|
||||||
return (STATUS_USER_APC);
|
|
||||||
}
|
}
|
||||||
} else if ((CurrentThread->ApcState.UserApcPending) && (WaitMode != KernelMode)) {
|
|
||||||
DPRINT1("Alertability failed\n");
|
/* If there are User APCs Pending and we are waiting in usermode, then we must notify the caller */
|
||||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
} else if ((CurrentThread->ApcState.UserApcPending) && (WaitMode == UserMode)) {
|
||||||
return (STATUS_USER_APC);
|
DPRINT1("APCs are Pending\n");
|
||||||
|
WaitStatus = STATUS_USER_APC;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -659,7 +652,7 @@ KeWaitForMultipleObjects(ULONG Count,
|
||||||
/*
|
/*
|
||||||
* Set up the wait
|
* Set up the wait
|
||||||
*/
|
*/
|
||||||
CurrentThread->WaitStatus = STATUS_UNSUCCESSFUL;
|
CurrentThread->WaitStatus = WaitStatus;;
|
||||||
|
|
||||||
for (i = 0; i < Count; i++)
|
for (i = 0; i < Count; i++)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue