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 *****************************************************************/
41 KeInitializeMutex(IN PKMUTEX Mutex,
44 KeInitializeDispatcherHeader(&Mutex->Header,
46 sizeof(KMUTEX) / sizeof(ULONG),
48 Mutex->MutantListEntry.Flink = NULL;
49 Mutex->MutantListEntry.Blink = NULL;
50 Mutex->OwnerThread = NULL;
51 Mutex->Abandoned = FALSE;
52 Mutex->ApcDisable = 1;
56 KeReadStateMutex(IN PKMUTEX Mutex)
58 return(Mutex->Header.SignalState);
62 KeReleaseMutex(IN PKMUTEX Mutex,
65 KeAcquireDispatcherDatabaseLock(Wait);
66 if (Mutex->OwnerThread != KeGetCurrentThread())
68 DbgPrint("THREAD_NOT_MUTEX_OWNER: Mutex %p\n", Mutex);
69 KeBugCheck(0); /* THREAD_NOT_MUTEX_OWNER */
71 Mutex->Header.SignalState++;
72 assert(Mutex->Header.SignalState <= 1);
73 if (Mutex->Header.SignalState == 1)
75 Mutex->OwnerThread = NULL;
76 if (Mutex->MutantListEntry.Flink && Mutex->MutantListEntry.Blink)
77 RemoveEntryList(&Mutex->MutantListEntry);
78 KeDispatcherObjectWake(&Mutex->Header);
80 KeReleaseDispatcherDatabaseLock(Wait);
85 KeWaitForMutexObject(IN PKMUTEX Mutex,
86 IN KWAIT_REASON WaitReason,
87 IN KPROCESSOR_MODE WaitMode,
89 IN PLARGE_INTEGER Timeout)
91 return(KeWaitForSingleObject(Mutex,WaitReason,WaitMode,Alertable,Timeout));
96 KeInitializeMutant(IN PKMUTANT Mutant,
97 IN BOOLEAN InitialOwner)
99 if (InitialOwner == TRUE)
101 KeInitializeDispatcherHeader(&Mutant->Header,
103 sizeof(KMUTANT) / sizeof(ULONG),
105 InsertTailList(&KeGetCurrentThread()->MutantListHead,
106 &Mutant->MutantListEntry);
107 Mutant->OwnerThread = KeGetCurrentThread();
111 KeInitializeDispatcherHeader(&Mutant->Header,
113 sizeof(KMUTANT) / sizeof(ULONG),
115 Mutant->MutantListEntry.Flink = NULL;
116 Mutant->MutantListEntry.Blink = NULL;
117 Mutant->OwnerThread = NULL;
119 Mutant->Abandoned = FALSE;
120 Mutant->ApcDisable = 0;
124 KeReadStateMutant(IN PKMUTANT Mutant)
126 return(Mutant->Header.SignalState);
130 KeReleaseMutant(IN PKMUTANT Mutant,
131 IN KPRIORITY Increment,
135 KeAcquireDispatcherDatabaseLock(Wait);
136 if (Abandon == FALSE)
138 if (Mutant->OwnerThread != NULL && Mutant->OwnerThread != KeGetCurrentThread())
140 DbgPrint("THREAD_NOT_MUTEX_OWNER: Mutant->OwnerThread %p CurrentThread %p\n",
142 KeGetCurrentThread());
143 KeBugCheck(0); /* THREAD_NOT_MUTEX_OWNER */
145 Mutant->Header.SignalState++;
146 assert(Mutant->Header.SignalState <= 1);
150 if (Mutant->OwnerThread != NULL)
152 Mutant->Header.SignalState = 1;
153 Mutant->Abandoned = TRUE;
157 if (Mutant->Header.SignalState == 1)
159 Mutant->OwnerThread = NULL;
160 if (Mutant->MutantListEntry.Flink && Mutant->MutantListEntry.Blink)
161 RemoveEntryList(&Mutant->MutantListEntry);
162 KeDispatcherObjectWake(&Mutant->Header);
165 KeReleaseDispatcherDatabaseLock(Wait);