ReactOS  0.4.13-dev-249-gcba1a2f
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;
26  KIRQL OldIrql;
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 }
struct _KMUTANT KMUTANT
#define InsertTailList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
smooth NULL
Definition: ftsmooth.c:416
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
FORCEINLINE VOID KiReleaseDispatcherLock(IN KIRQL OldIrql)
Definition: ke_x.h:152
FORCEINLINE KIRQL KiAcquireDispatcherLock(VOID)
Definition: ke_x.h:144
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
unsigned int ULONG
Definition: retypes.h:1
#define KeGetCurrentThread
Definition: hal.h:44
_In_ BOOLEAN InitialOwner
Definition: kefuncs.h:590
LIST_ENTRY MutantListHead
Definition: ketypes.h:1899

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 }
struct _KMUTANT KMUTEX
Definition: Mutex.h:15
smooth NULL
Definition: ftsmooth.c:416
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
unsigned int ULONG
Definition: retypes.h:1

Referenced by AfdCreateSocket(), CdRomCreateDeviceObject(), 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 {
103  KIRQL OldIrql;
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 }
#define ASSERT_IRQL_LESS_OR_EQUAL(x)
Definition: debug.h:251
#define TRUE
Definition: types.h:120
#define ExRaiseStatus
Definition: ntoskrnl.h:95
VOID FASTCALL KiWaitTest(PVOID Object, KPRIORITY Increment)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define STATUS_MUTANT_NOT_OWNED
Definition: ntstatus.h:292
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
long LONG
Definition: pedump.c:60
ULONG WaitNext
Definition: ketypes.h:1586
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define ASSERT_MUTANT(Object)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
_In_ PLARGE_INTEGER _In_opt_ PTIMER_APC_ROUTINE _In_opt_ PVOID _In_ BOOLEAN _In_opt_ LONG _Out_opt_ PBOOLEAN PreviousState
Definition: zwfuncs.h:428
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
FORCEINLINE VOID KiReleaseDispatcherLock(IN KIRQL OldIrql)
Definition: ke_x.h:152
FORCEINLINE KIRQL KiAcquireDispatcherLock(VOID)
Definition: ke_x.h:144
#define KeGetCurrentThread
Definition: hal.h:44
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG Increment
Definition: CrNtStubs.h:42
#define STATUS_ABANDONED
Definition: ntstatus.h:75
KIRQL WaitIrql
Definition: ketypes.h:1685
IN BOOLEAN Wait
Definition: fatprocs.h:1529

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

◆ KeReleaseMutex()

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