- Remove some duplicated/useless code and use internal forward exports instead.

- Set kernel apc pending flag when needed in KeReleaseMutant
- Optimize check for kernel apc delivery in KeReleaseMutant
- Raise right exception in KeReleaseMutant
- Simplify KeInitializeMutant and remove some duplicated operations.
- Remove duplicated listhead initialization in KeInitiializeMutex
- Use correct increment in KeReleaseMutex

svn path=/trunk/; revision=18185
This commit is contained in:
Alex Ionescu 2005-10-01 08:58:49 +00:00
parent f57183be46
commit 35eb408157
2 changed files with 46 additions and 77 deletions

View file

@ -27,33 +27,30 @@ STDCALL
KeInitializeMutant(IN PKMUTANT Mutant,
IN BOOLEAN InitialOwner)
{
ULONG Signaled = TRUE;
PKTHREAD CurrentThread = NULL;
PKTHREAD CurrentThread;
KIRQL OldIrql;
DPRINT("KeInitializeMutant: %x\n", Mutant);
/* Check if we have an initial owner */
if (InitialOwner == TRUE) {
/* In this case, the object is not signaled */
Signaled = FALSE;
if (InitialOwner == TRUE)
{
/* We also need to associate a thread */
CurrentThread = KeGetCurrentThread();
Mutant->OwnerThread = CurrentThread;
/* We're about to touch the Thread, so lock the Dispatcher */
OldIrql = KeAcquireDispatcherDatabaseLock();
/* And insert it into its list */
InsertTailList(&CurrentThread->MutantListHead, &Mutant->MutantListEntry);
InsertTailList(&CurrentThread->MutantListHead,
&Mutant->MutantListEntry);
/* Release Dispatcher Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
DPRINT("Mutant with Initial Owner\n");
} else {
}
else
{
/* In this case, we don't have an owner yet */
Mutant->OwnerThread = NULL;
}
@ -62,10 +59,9 @@ KeInitializeMutant(IN PKMUTANT Mutant,
KeInitializeDispatcherHeader(&Mutant->Header,
MutantObject,
sizeof(KMUTANT) / sizeof(ULONG),
Signaled);
InitialOwner ? FALSE : TRUE);
/* Initialize the default data */
Mutant->OwnerThread = CurrentThread;
Mutant->Abandoned = FALSE;
Mutant->ApcDisable = 0;
}
@ -80,18 +76,16 @@ KeInitializeMutex(IN PKMUTEX Mutex,
{
DPRINT("KeInitializeMutex: %x\n", Mutex);
/* Set up the Dispatcher Header */
KeInitializeDispatcherHeader(&Mutex->Header,
MutantObject,
sizeof(KMUTEX) / sizeof(ULONG),
1);
TRUE);
/* Initialize the default data */
Mutex->OwnerThread = NULL;
Mutex->Abandoned = FALSE;
Mutex->ApcDisable = 1;
InitializeListHead(&Mutex->Header.WaitListHead);
}
/*
@ -105,17 +99,6 @@ KeReadStateMutant(IN PKMUTANT Mutant)
return(Mutant->Header.SignalState);
}
/*
* @implemented
*/
LONG
STDCALL
KeReadStateMutex(IN PKMUTEX Mutex)
{
/* Return the Signal State */
return(Mutex->Header.SignalState);
}
/*
* @implemented
*/
@ -129,7 +112,6 @@ KeReleaseMutant(IN PKMUTANT Mutant,
KIRQL OldIrql;
LONG PreviousState;
PKTHREAD CurrentThread = KeGetCurrentThread();
DPRINT("KeReleaseMutant: %x\n", Mutant);
/* Lock the Dispatcher Database */
@ -139,22 +121,26 @@ KeReleaseMutant(IN PKMUTANT Mutant,
PreviousState = Mutant->Header.SignalState;
/* Check if it is to be abandonned */
if (Abandon == FALSE) {
if (Abandon == FALSE)
{
/* Make sure that the Owner Thread is the current Thread */
if (Mutant->OwnerThread != CurrentThread) {
if (Mutant->OwnerThread != CurrentThread)
{
DPRINT1("Trying to touch a Mutant that the caller doesn't own!\n");
/* Release the lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
DPRINT1("Trying to touch a Mutant that the caller doesn't own!\n");
ExRaiseStatus(STATUS_MUTANT_NOT_OWNED);
/* Raise an exception */
ExRaiseStatus(Mutant->Abandoned ? STATUS_ABANDONED :
STATUS_MUTANT_NOT_OWNED);
}
/* If the thread owns it, then increase the signal state */
Mutant->Header.SignalState++;
} else {
}
else
{
/* It's going to be abandonned */
DPRINT("Abandonning the Mutant\n");
Mutant->Header.SignalState = 1;
@ -162,24 +148,27 @@ KeReleaseMutant(IN PKMUTANT Mutant,
}
/* Check if the signal state is only single */
if (Mutant->Header.SignalState == 1) {
if (Mutant->Header.SignalState == 1)
{
/* Check if it's below 0 now */
if (PreviousState <= 0) {
if (PreviousState <= 0)
{
/* Remove the mutant from the list */
DPRINT("Removing Mutant\n");
DPRINT("Removing Mutant %p\n", Mutant);
RemoveEntryList(&Mutant->MutantListEntry);
/* Reenable APCs */
DPRINT("Re-enabling APCs\n");
CurrentThread->KernelApcDisable += Mutant->ApcDisable;
/* Force an Interrupt if Apcs are pending */
if (!IsListEmpty(&CurrentThread->ApcState.ApcListHead[KernelMode])) {
/* Make sure they aren't disabled though */
if (!CurrentThread->KernelApcDisable) {
/* Check if the thread has APCs enabled */
if (!CurrentThread->KernelApcDisable)
{
/* Check if any are pending */
if (!IsListEmpty(&CurrentThread->ApcState.ApcListHead[KernelMode]))
{
/* Set Kernel APC Pending */
CurrentThread->ApcState.KernelApcPending = TRUE;
/* Request the Interrupt */
DPRINT("Requesting APC Interupt\n");
@ -193,8 +182,8 @@ KeReleaseMutant(IN PKMUTANT Mutant,
/* Check if the Wait List isn't empty */
DPRINT("Checking whether to wake the Mutant\n");
if (!IsListEmpty(&Mutant->Header.WaitListHead)) {
if (!IsListEmpty(&Mutant->Header.WaitListHead))
{
/* Wake the Mutant */
DPRINT("Waking the Mutant\n");
KiWaitTest(&Mutant->Header, Increment);
@ -202,13 +191,13 @@ KeReleaseMutant(IN PKMUTANT Mutant,
}
/* If the Wait is true, then return with a Wait and don't unlock the Dispatcher Database */
if (Wait == FALSE) {
if (Wait == FALSE)
{
/* Release the Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
} else {
}
else
{
/* Set a wait */
CurrentThread->WaitNext = TRUE;
CurrentThread->WaitIrql = OldIrql;
@ -226,28 +215,8 @@ STDCALL
KeReleaseMutex(IN PKMUTEX Mutex,
IN BOOLEAN Wait)
{
/* There's no difference at this level between the two */
return KeReleaseMutant(Mutex, IO_NO_INCREMENT, FALSE, Wait);
}
/*
* @implemented
*/
NTSTATUS
STDCALL
KeWaitForMutexObject(IN PKMUTEX Mutex,
IN KWAIT_REASON WaitReason,
IN KPROCESSOR_MODE WaitMode,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER Timeout)
{
/* This is a simple macro. Export the function here though */
return KeWaitForSingleObject(Mutex,
WaitReason,
WaitMode,
Alertable,
Timeout);
return KeReleaseMutant(Mutex, 1, FALSE, Wait);
}
/* EOF */

View file

@ -588,7 +588,7 @@ KeQueryTimeIncrement@0
KeRaiseUserException@4
KeReadStateEvent@4
KeReadStateMutant@4
KeReadStateMutex@4
KeReadStateMutex@4=KeReadStateMutant@4
KeReadStateQueue@4
KeReadStateSemaphore@4
KeReadStateTimer@4
@ -645,7 +645,7 @@ KeUpdateSystemTime@8
KeUnstackDetachProcess@4
KeUserModeCallback@20
KeWaitForMultipleObjects@32
KeWaitForMutexObject@20
KeWaitForMutexObject@20=KeWaitForSingleObject@20
KeWaitForSingleObject@20
@KefAcquireSpinLockAtDpcLevel@4
@KefReleaseSpinLockFromDpcLevel@4