mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
- Add ASSERT_APC definition.
- Fix KeRemoveQueueApc comment header and clean up function. - Acquire dispatcher lock at DPC level during ApcListEntry read/write. svn path=/trunk/; revision=24053
This commit is contained in:
parent
4b35027c0f
commit
43a412db60
2 changed files with 34 additions and 21 deletions
|
@ -1085,9 +1085,12 @@ typedef struct _KLOCK_QUEUE_HANDLE {
|
||||||
#define DPC_NORMAL 0
|
#define DPC_NORMAL 0
|
||||||
#define DPC_THREADED 1
|
#define DPC_THREADED 1
|
||||||
|
|
||||||
#define ASSERT_DPC(Object) \
|
#define ASSERT_APC(Object) \
|
||||||
ASSERT(((Object)->Type == 0) || \
|
ASSERT((Object)->Type == ApcObject)
|
||||||
((Object)->Type == DpcObject) || \
|
|
||||||
|
#define ASSERT_DPC(Object) \
|
||||||
|
ASSERT(((Object)->Type == 0) || \
|
||||||
|
((Object)->Type == DpcObject) || \
|
||||||
((Object)->Type == ThreadedDpcObject))
|
((Object)->Type == ThreadedDpcObject))
|
||||||
|
|
||||||
typedef struct _KDPC
|
typedef struct _KDPC
|
||||||
|
|
|
@ -774,59 +774,69 @@ KeFlushQueueApc(IN PKTHREAD Thread,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*++
|
/*++
|
||||||
* KeRemoveQueueApc
|
* @name KeRemoveQueueApc
|
||||||
|
* @implemented NT4
|
||||||
*
|
*
|
||||||
* The KeRemoveQueueApc routine removes a given APC object from the system
|
* The KeRemoveQueueApc routine removes a given APC object from the system
|
||||||
* APC queue.
|
* APC queue.
|
||||||
*
|
*
|
||||||
* Params:
|
* @params Apc
|
||||||
* APC - Pointer to an initialized APC object that was queued by calling
|
* Pointer to an initialized APC object that was queued by calling
|
||||||
* KeInsertQueueApc.
|
* KeInsertQueueApc.
|
||||||
*
|
*
|
||||||
* Returns:
|
* @return TRUE if the APC Object is in the APC Queue. Otherwise, no operation
|
||||||
* TRUE if the APC Object is in the APC Queue. If it isn't, no operation is
|
* is performed and FALSE is returned.
|
||||||
* performed and FALSE is returned.
|
|
||||||
*
|
*
|
||||||
* Remarks:
|
* @remarks If the given APC Object is currently queued, it is removed from the
|
||||||
* If the given APC Object is currently queued, it is removed from the queue
|
* queue and any calls to the registered routines are cancelled.
|
||||||
* and any calls to the registered routines are cancelled.
|
|
||||||
*
|
*
|
||||||
* Callers of KeLeaveCriticalRegion can be running at any IRQL.
|
* Callers of this routine must be running at IRQL <= DISPATCH_LEVEL.
|
||||||
*
|
*
|
||||||
*--*/
|
*--*/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
STDCALL
|
NTAPI
|
||||||
KeRemoveQueueApc(PKAPC Apc)
|
KeRemoveQueueApc(IN PKAPC Apc)
|
||||||
{
|
{
|
||||||
PKTHREAD Thread = Apc->Thread;
|
PKTHREAD Thread = Apc->Thread;
|
||||||
PKAPC_STATE ApcState;
|
PKAPC_STATE ApcState;
|
||||||
BOOLEAN Inserted;
|
BOOLEAN Inserted;
|
||||||
KLOCK_QUEUE_HANDLE ApcLock;
|
KLOCK_QUEUE_HANDLE ApcLock;
|
||||||
|
ASSERT_APC(Apc);
|
||||||
|
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||||
|
|
||||||
/* Get the APC lock */
|
/* Get the APC lock */
|
||||||
KiAcquireApcLock(Thread, &ApcLock);
|
KiAcquireApcLock(Thread, &ApcLock);
|
||||||
|
|
||||||
/* Check if it's inserted */
|
/* Check if it's inserted */
|
||||||
if ((Inserted = Apc->Inserted))
|
Inserted = Apc->Inserted;
|
||||||
|
if (Inserted)
|
||||||
{
|
{
|
||||||
/* Remove it from the Queue*/
|
/* Set it as non-inserted and get the APC state */
|
||||||
Apc->Inserted = FALSE;
|
Apc->Inserted = FALSE;
|
||||||
ApcState = Thread->ApcStatePointer[(int)Apc->ApcStateIndex];
|
ApcState = Thread->ApcStatePointer[(SCHAR)Apc->ApcStateIndex];
|
||||||
|
|
||||||
|
/* Acquire the dispatcher lock and remove it from the list */
|
||||||
|
KiAcquireDispatcherLockAtDpcLevel();
|
||||||
RemoveEntryList(&Apc->ApcListEntry);
|
RemoveEntryList(&Apc->ApcListEntry);
|
||||||
|
|
||||||
/* If the Queue is completely empty, then no more APCs are pending */
|
/* If the Queue is completely empty, then no more APCs are pending */
|
||||||
if (IsListEmpty(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode]))
|
if (IsListEmpty(&ApcState->ApcListHead[Apc->ApcMode]))
|
||||||
{
|
{
|
||||||
/* Set the correct State based on the Apc Mode */
|
/* Set the correct state based on the APC Mode */
|
||||||
if (Apc->ApcMode == KernelMode)
|
if (Apc->ApcMode == KernelMode)
|
||||||
{
|
{
|
||||||
|
/* No more pending kernel APCs */
|
||||||
ApcState->KernelApcPending = FALSE;
|
ApcState->KernelApcPending = FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* No more pending user APCs */
|
||||||
ApcState->UserApcPending = FALSE;
|
ApcState->UserApcPending = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Release dispatcher lock */
|
||||||
|
KiReleaseDispatcherLockFromDpcLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release the lock and return */
|
/* Release the lock and return */
|
||||||
|
|
Loading…
Reference in a new issue