mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +00:00
- 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:
parent
f57183be46
commit
35eb408157
2 changed files with 46 additions and 77 deletions
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue