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