3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * PROJECT: ReactOS kernel
22 * FILE: ntoskrnl/ke/mutex.c
23 * PURPOSE: Implements mutex
24 * PROGRAMMER: David Welch (welch@mcmail.com)
29 /* INCLUDES *****************************************************************/
31 #include <ddk/ntddk.h>
32 #include <internal/ke.h>
33 #include <internal/ps.h>
34 #include <internal/id.h>
36 #include <internal/debug.h>
38 /* FUNCTIONS *****************************************************************/
43 KeInitializeMutex(IN PKMUTEX Mutex,
46 KeInitializeDispatcherHeader(&Mutex->Header,
48 sizeof(KMUTEX) / sizeof(ULONG),
50 Mutex->MutantListEntry.Flink = NULL;
51 Mutex->MutantListEntry.Blink = NULL;
52 Mutex->OwnerThread = NULL;
53 Mutex->Abandoned = FALSE;
54 Mutex->ApcDisable = 1;
58 KeReadStateMutex(IN PKMUTEX Mutex)
60 return(Mutex->Header.SignalState);
64 KeReleaseMutex(IN PKMUTEX Mutex,
67 KeAcquireDispatcherDatabaseLock(Wait);
68 if (Mutex->OwnerThread != KeGetCurrentThread())
70 DbgPrint("THREAD_NOT_MUTEX_OWNER: Mutex %p\n", Mutex);
71 KeBugCheck(0); /* THREAD_NOT_MUTEX_OWNER */
73 Mutex->Header.SignalState++;
74 assert(Mutex->Header.SignalState <= 1);
75 if (Mutex->Header.SignalState == 1)
77 Mutex->OwnerThread = NULL;
78 if (Mutex->MutantListEntry.Flink && Mutex->MutantListEntry.Blink)
79 RemoveEntryList(&Mutex->MutantListEntry);
80 KeDispatcherObjectWake(&Mutex->Header);
82 KeReleaseDispatcherDatabaseLock(Wait);
87 KeWaitForMutexObject(IN PKMUTEX Mutex,
88 IN KWAIT_REASON WaitReason,
89 IN KPROCESSOR_MODE WaitMode,
91 IN PLARGE_INTEGER Timeout)
93 return(KeWaitForSingleObject(Mutex,WaitReason,WaitMode,Alertable,Timeout));
96 #endif /* LIBCAPTIVE */
99 KeInitializeMutant(IN PKMUTANT Mutant,
100 IN BOOLEAN InitialOwner)
102 if (InitialOwner == TRUE)
104 KeInitializeDispatcherHeader(&Mutant->Header,
106 sizeof(KMUTANT) / sizeof(ULONG),
108 InsertTailList(&KeGetCurrentThread()->MutantListHead,
109 &Mutant->MutantListEntry);
110 Mutant->OwnerThread = KeGetCurrentThread();
114 KeInitializeDispatcherHeader(&Mutant->Header,
116 sizeof(KMUTANT) / sizeof(ULONG),
118 Mutant->MutantListEntry.Flink = NULL;
119 Mutant->MutantListEntry.Blink = NULL;
120 Mutant->OwnerThread = NULL;
122 Mutant->Abandoned = FALSE;
123 Mutant->ApcDisable = 0;
129 KeReadStateMutant(IN PKMUTANT Mutant)
131 return(Mutant->Header.SignalState);
134 #endif /* LIBCAPTIVE */
137 KeReleaseMutant(IN PKMUTANT Mutant,
138 IN KPRIORITY Increment,
142 KeAcquireDispatcherDatabaseLock(Wait);
143 if (Abandon == FALSE)
145 if (Mutant->OwnerThread != NULL && Mutant->OwnerThread != KeGetCurrentThread())
147 DbgPrint("THREAD_NOT_MUTEX_OWNER: Mutant->OwnerThread %p CurrentThread %p\n",
149 KeGetCurrentThread());
150 KeBugCheck(0); /* THREAD_NOT_MUTEX_OWNER */
152 if (Mutant->Header.SignalState==0)
154 Mutant->Header.SignalState++;
158 /* ntfs.sys behaviour: KeInitializeMutant(,FALSE); KeReleaseMutant(,0,FALSE,FALSE;
161 DbgPrint("WARNING: Releasing already unlocked KMUTANT %p CurrentThread %p !!!\n",
162 Mutant,KeGetCurrentThread());
164 assert(Mutant->Header.SignalState <= 1);
168 if (Mutant->OwnerThread != NULL)
170 Mutant->Header.SignalState = 1;
171 Mutant->Abandoned = TRUE;
175 if (Mutant->Header.SignalState == 1)
177 Mutant->OwnerThread = NULL;
178 if (Mutant->MutantListEntry.Flink && Mutant->MutantListEntry.Blink)
179 RemoveEntryList(&Mutant->MutantListEntry);
181 KeDispatcherObjectWake(&Mutant->Header);
182 #endif /* LIBCAPTIVE */
185 KeReleaseDispatcherDatabaseLock(Wait);