ReactOS 0.4.16-dev-329-g9223134
mutex.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for mutex.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID NTAPI KeInitializeMutant (IN PKMUTANT Mutant, IN BOOLEAN InitialOwner)
 
VOID NTAPI KeInitializeMutex (IN PKMUTEX Mutex, IN ULONG Level)
 
LONG NTAPI KeReadStateMutant (IN PKMUTANT Mutant)
 
LONG NTAPI KeReleaseMutant (IN PKMUTANT Mutant, IN KPRIORITY Increment, IN BOOLEAN Abandon, IN BOOLEAN Wait)
 
LONG NTAPI KeReleaseMutex (IN PKMUTEX Mutex, IN BOOLEAN Wait)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file mutex.c.

Function Documentation

◆ KeInitializeMutant()

VOID NTAPI KeInitializeMutant ( IN PKMUTANT  Mutant,
IN BOOLEAN  InitialOwner 
)

Definition at line 22 of file mutex.c.

24{
25 PKTHREAD CurrentThread;
27
28 /* Check if we have an initial owner */
29 if (InitialOwner)
30 {
31 /* We also need to associate a thread */
32 CurrentThread = KeGetCurrentThread();
33 Mutant->OwnerThread = CurrentThread;
34
35 /* We're about to touch the Thread, so lock the Dispatcher */
37
38 /* And insert it into its list */
39 InsertTailList(&CurrentThread->MutantListHead,
40 &Mutant->MutantListEntry);
41
42 /* Release Dispatcher Lock */
44 }
45 else
46 {
47 /* In this case, we don't have an owner yet */
48 Mutant->OwnerThread = NULL;
49 }
50
51 /* Now we set up the Dispatcher Header */
52 Mutant->Header.Type = MutantObject;
53 Mutant->Header.Size = sizeof(KMUTANT) / sizeof(ULONG);
54 Mutant->Header.SignalState = InitialOwner ? 0 : 1;
55 InitializeListHead(&(Mutant->Header.WaitListHead));
56
57 /* Initialize the default data */
58 Mutant->Abandoned = FALSE;
59 Mutant->ApcDisable = 0;
60}
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define InsertTailList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeGetCurrentThread
Definition: hal.h:55
FORCEINLINE VOID KiReleaseDispatcherLock(IN KIRQL OldIrql)
Definition: ke_x.h:157
FORCEINLINE KIRQL KiAcquireDispatcherLock(VOID)
Definition: ke_x.h:149
@ MutantObject
Definition: ketypes.h:408
LIST_ENTRY MutantListHead
Definition: ketypes.h:2009
uint32_t ULONG
Definition: typedefs.h:59
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
_In_ BOOLEAN InitialOwner
Definition: kefuncs.h:565
struct _KMUTANT KMUTANT

Referenced by MmArmInitSystem(), and NtCreateMutant().

◆ KeInitializeMutex()

VOID NTAPI KeInitializeMutex ( IN PKMUTEX  Mutex,
IN ULONG  Level 
)

Definition at line 67 of file mutex.c.

69{
70 /* Set up the Dispatcher Header */
71 Mutex->Header.Type = MutantObject;
72 Mutex->Header.Size = sizeof(KMUTEX) / sizeof(ULONG);
73 Mutex->Header.SignalState = 1;
74 InitializeListHead(&(Mutex->Header.WaitListHead));
75
76 /* Initialize the default data */
77 Mutex->OwnerThread = NULL;
78 Mutex->Abandoned = FALSE;
79 Mutex->ApcDisable = 1;
80}
Definition: Mutex.h:16
struct _KMUTANT KMUTEX

Referenced by AfdCreateSocket(), ClasspInitializePolling(), DiskInitFdo(), DriverEntry(), ExpInitializeProfileImplementation(), IKsFilterFactory_fnInitialize(), InitializeGlobalData(), IntVideoPortCreateAdapterDeviceObject(), KsAllocateDeviceHeader(), KsInitializeDevice(), KspCreateFilter(), KspCreatePin(), RawInitializeVcb(), RxDriverEntry(), SacInitializeMutexLock(), TestMutex(), and VideoPortInitialize().

◆ KeReadStateMutant()

LONG NTAPI KeReadStateMutant ( IN PKMUTANT  Mutant)

Definition at line 87 of file mutex.c.

88{
89 /* Return the Signal State */
90 return Mutant->Header.SignalState;
91}

Referenced by NtQueryMutant(), and RawCheckForDismount().

◆ KeReleaseMutant()

LONG NTAPI KeReleaseMutant ( IN PKMUTANT  Mutant,
IN KPRIORITY  Increment,
IN BOOLEAN  Abandon,
IN BOOLEAN  Wait 
)

Definition at line 98 of file mutex.c.

102{
105 PKTHREAD CurrentThread = KeGetCurrentThread();
106 BOOLEAN EnableApc = FALSE;
107 ASSERT_MUTANT(Mutant);
109
110 /* Lock the Dispatcher Database */
112
113 /* Save the Previous State */
114 PreviousState = Mutant->Header.SignalState;
115
116 /* Check if it is to be abandonned */
117 if (Abandon == FALSE)
118 {
119 /* Make sure that the Owner Thread is the current Thread */
120 if (Mutant->OwnerThread != CurrentThread)
121 {
122 /* Release the lock */
124
125 /* Raise an exception */
126 ExRaiseStatus(Mutant->Abandoned ? STATUS_ABANDONED :
128 }
129
130 /* If the thread owns it, then increase the signal state */
131 Mutant->Header.SignalState++;
132 }
133 else
134 {
135 /* It's going to be abandonned */
136 Mutant->Header.SignalState = 1;
137 Mutant->Abandoned = TRUE;
138 }
139
140 /* Check if the signal state is only single */
141 if (Mutant->Header.SignalState == 1)
142 {
143 /* Check if it's below 0 now */
144 if (PreviousState <= 0)
145 {
146 /* Remove the mutant from the list */
147 RemoveEntryList(&Mutant->MutantListEntry);
148
149 /* Save if we need to re-enable APCs */
150 EnableApc = Mutant->ApcDisable;
151 }
152
153 /* Remove the Owning Thread and wake it */
154 Mutant->OwnerThread = NULL;
155
156 /* Check if the Wait List isn't empty */
157 if (!IsListEmpty(&Mutant->Header.WaitListHead))
158 {
159 /* Wake the Mutant */
160 KiWaitTest(&Mutant->Header, Increment);
161 }
162 }
163
164 /* Check if the caller wants to wait after this release */
165 if (Wait == FALSE)
166 {
167 /* Release the Lock */
169 }
170 else
171 {
172 /* Set a wait */
173 CurrentThread->WaitNext = TRUE;
174 CurrentThread->WaitIrql = OldIrql;
175 }
176
177 /* Check if we need to re-enable APCs */
178 if (EnableApc) KeLeaveCriticalRegion();
179
180 /* Return the previous state */
181 return PreviousState;
182}
unsigned char BOOLEAN
#define TRUE
Definition: types.h:120
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG Increment
Definition: CrNtStubs.h:46
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
VOID FASTCALL KiWaitTest(PVOID Object, KPRIORITY Increment)
#define ExRaiseStatus
Definition: ntoskrnl.h:114
#define STATUS_MUTANT_NOT_OWNED
Definition: ntstatus.h:306
#define STATUS_ABANDONED
Definition: ntstatus.h:75
long LONG
Definition: pedump.c:60
#define ASSERT_IRQL_LESS_OR_EQUAL(x)
Definition: debug.h:251
KIRQL WaitIrql
Definition: ketypes.h:1795
ULONG WaitNext
Definition: ketypes.h:1696
_In_ WDF_POWER_DEVICE_STATE PreviousState
Definition: wdfdevice.h:829
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
#define ASSERT_MUTANT(Object)

Referenced by ExpDeleteMutant(), KeReleaseMutex(), MiFindInitializationCode(), MmAddVerifierThunks(), MmLoadSystemImage(), MmUnloadSystemImage(), NtReleaseMutant(), and NtSignalAndWaitForSingleObject().

◆ KeReleaseMutex()

LONG NTAPI KeReleaseMutex ( IN PKMUTEX  Mutex,
IN BOOLEAN  Wait 
)

Definition at line 189 of file mutex.c.

191{
193
194 /* There's no difference at this level between the two */
196}
#define MUTANT_INCREMENT
Definition: extypes.h:84
LONG NTAPI KeReleaseMutant(IN PKMUTANT Mutant, IN KPRIORITY Increment, IN BOOLEAN Abandon, IN BOOLEAN Wait)
Definition: mutex.c:98

Referenced by _IRQL_requires_max_(), _KsEdit(), ClasspSetMediaChangeStateEx(), DeviceSetMediaChangeStateEx(), DiskIoctlVerifyThread(), IKsDevice_fnReleaseDevice(), IKsFilter_DispatchCreatePin(), IKsFilter_DispatchDeviceIoControl(), IKsFilter_fnAddProcessPin(), IKsFilter_fnRemoveProcessPin(), IKsPin_PinAllocatorFramingPropertyHandler(), IKsPin_PinDataFormatPropertyHandler(), IKsPin_PinStatePropertyHandler(), IKsProcessingObject_fnProcessingObjectWork(), IKsProcessingObject_fnReset(), IntInt10CallBios(), KsAddItemToObjectBag(), KsCopyObjectBagItems(), KsFilterReleaseProcessingMutex(), KsFreeObjectBag(), KsPinReleaseProcessingMutex(), KspSynchronizedEventRoutine(), KsReleaseControl(), KsRemoveItemFromObjectBag(), NtStartProfile(), NtStopProfile(), CMiniportWaveStreamCMI::prepareStream(), RawCheckForDismount(), RawCleanup(), RawClose(), RawCreate(), RawFileSystemControl(), RawUserFsCtrl(), SacReleaseMutexLock(), CMiniportWaveStreamCMI::setDACChannels(), CMiniportWaveStreamCMI::setupSPDIFPlayback(), SocketStateUnlock(), STDMETHODIMP_(), TestMutex(), and VideoPortReleaseDeviceLock().