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.
19 /* $Id: mutex.c,v 1.13 2003/07/10 17:44:06 royce Exp $
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
);