73d640b26ae2726505231d3381444603104502a4
[reactos.git] / reactos / ntoskrnl / cc / ccmutex.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/cc/ccmutex.c
5 * PURPOSE: Implements the Broken Mutex Implementation for the broken Cc
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #include <ntoskrnl.h>
12 #include <internal/debug.h>
13
14 /* FUNCTIONS *****************************************************************/
15
16 VOID
17 FASTCALL
18 CcAcquireBrokenMutexUnsafe(PFAST_MUTEX FastMutex)
19 {
20 ASSERT(KeGetCurrentThread() == NULL ||
21 FastMutex->Owner != KeGetCurrentThread());
22 ASSERT(KeGetCurrentIrql() == APC_LEVEL ||
23 KeGetCurrentThread() == NULL ||
24 KeGetCurrentThread()->KernelApcDisable);
25
26 InterlockedIncrementUL(&FastMutex->Contention);
27 while (InterlockedExchange(&FastMutex->Count, 0) == 0)
28 {
29 KeWaitForSingleObject(&FastMutex->Event,
30 Executive,
31 KernelMode,
32 FALSE,
33 NULL);
34 }
35 InterlockedDecrementUL(&FastMutex->Contention);
36 FastMutex->Owner = KeGetCurrentThread();
37 }
38
39 VOID
40 FASTCALL
41 CcReleaseBrokenMutexUnsafe(PFAST_MUTEX FastMutex)
42 {
43 ASSERT(KeGetCurrentThread() == NULL ||
44 FastMutex->Owner == KeGetCurrentThread());
45 ASSERT(KeGetCurrentIrql() == APC_LEVEL ||
46 KeGetCurrentThread() == NULL ||
47 KeGetCurrentThread()->KernelApcDisable);
48
49 FastMutex->Owner = NULL;
50 InterlockedExchange(&FastMutex->Count, 1);
51 if (FastMutex->Contention > 0)
52 {
53 KeSetEvent(&FastMutex->Event, 0, FALSE);
54 }
55 }
56
57 VOID
58 FASTCALL
59 CcAcquireBrokenMutex(PFAST_MUTEX FastMutex)
60 {
61 KeEnterCriticalRegion();
62 CcAcquireBrokenMutexUnsafe(FastMutex);
63 }
64
65
66 VOID
67 FASTCALL
68 CcReleaseBrokenMutex(PFAST_MUTEX FastMutex)
69 {
70 CcReleaseBrokenMutexUnsafe(FastMutex);
71 KeLeaveCriticalRegion();
72 }
73
74 BOOLEAN
75 FASTCALL
76 CcTryToAcquireBrokenMutex(PFAST_MUTEX FastMutex)
77 {
78 KeEnterCriticalRegion();
79 if (InterlockedExchange(&FastMutex->Count, 0) == 1)
80 {
81 FastMutex->Owner = KeGetCurrentThread();
82 return(TRUE);
83 }
84 else
85 {
86 KeLeaveCriticalRegion();
87 return(FALSE);
88 }
89 }