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 *****************************************************************/
44 KeInitializeMutex(IN PKMUTEX Mutex,
47 KeInitializeDispatcherHeader(&Mutex->Header,
49 sizeof(KMUTEX) / sizeof(ULONG),
51 Mutex->MutantListEntry.Flink = NULL;
52 Mutex->MutantListEntry.Blink = NULL;
53 Mutex->OwnerThread = NULL;
54 Mutex->Abandoned = FALSE;
55 Mutex->ApcDisable = 1;
62 KeReadStateMutex(IN PKMUTEX Mutex)
64 return(Mutex->Header.SignalState);
71 KeReleaseMutex(IN PKMUTEX Mutex,
74 KeAcquireDispatcherDatabaseLock(Wait);
75 if (Mutex->OwnerThread != KeGetCurrentThread())
77 DbgPrint("THREAD_NOT_MUTEX_OWNER: Mutex %p\n", Mutex);
78 KEBUGCHECK(0); /* THREAD_NOT_MUTEX_OWNER */
80 Mutex->Header.SignalState++;
81 assert(Mutex->Header.SignalState <= 1);
82 if (Mutex->Header.SignalState == 1)
84 Mutex->OwnerThread = NULL;
85 if (Mutex->MutantListEntry.Flink && Mutex->MutantListEntry.Blink)
86 RemoveEntryList(&Mutex->MutantListEntry);
87 KeDispatcherObjectWake(&Mutex->Header);
89 KeReleaseDispatcherDatabaseLock(Wait);
97 KeWaitForMutexObject(IN PKMUTEX Mutex,
98 IN KWAIT_REASON WaitReason,
99 IN KPROCESSOR_MODE WaitMode,
100 IN BOOLEAN Alertable,
101 IN PLARGE_INTEGER Timeout)
103 return(KeWaitForSingleObject(Mutex,WaitReason,WaitMode,Alertable,Timeout));
111 KeInitializeMutant(IN PKMUTANT Mutant,
112 IN BOOLEAN InitialOwner)
114 if (InitialOwner == TRUE)
116 KeInitializeDispatcherHeader(&Mutant->Header,
118 sizeof(KMUTANT) / sizeof(ULONG),
120 InsertTailList(&KeGetCurrentThread()->MutantListHead,
121 &Mutant->MutantListEntry);
122 Mutant->OwnerThread = KeGetCurrentThread();
126 KeInitializeDispatcherHeader(&Mutant->Header,
128 sizeof(KMUTANT) / sizeof(ULONG),
130 Mutant->MutantListEntry.Flink = NULL;
131 Mutant->MutantListEntry.Blink = NULL;
132 Mutant->OwnerThread = NULL;
134 Mutant->Abandoned = FALSE;
135 Mutant->ApcDisable = 0;
142 KeReadStateMutant(IN PKMUTANT Mutant)
144 return(Mutant->Header.SignalState);
151 KeReleaseMutant(IN PKMUTANT Mutant,
152 IN KPRIORITY Increment,
156 KeAcquireDispatcherDatabaseLock(Wait);
157 if (Abandon == FALSE)
159 if (Mutant->OwnerThread != NULL && Mutant->OwnerThread != KeGetCurrentThread())
161 DbgPrint("THREAD_NOT_MUTEX_OWNER: Mutant->OwnerThread %p CurrentThread %p\n",
163 KeGetCurrentThread());
164 KEBUGCHECK(0); /* THREAD_NOT_MUTEX_OWNER */
166 Mutant->Header.SignalState++;
167 assert(Mutant->Header.SignalState <= 1);
171 if (Mutant->OwnerThread != NULL)
173 Mutant->Header.SignalState = 1;
174 Mutant->Abandoned = TRUE;
178 if (Mutant->Header.SignalState == 1)
180 Mutant->OwnerThread = NULL;
181 if (Mutant->MutantListEntry.Flink && Mutant->MutantListEntry.Blink)
182 RemoveEntryList(&Mutant->MutantListEntry);
183 KeDispatcherObjectWake(&Mutant->Header);
186 KeReleaseDispatcherDatabaseLock(Wait);