[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / io / iomgr / remlock.c
1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/io/remlock.c
5 * PURPOSE: Remove Lock Support
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 * Filip Navara (navaraf@reactos.org)
8 */
9
10 /* INCLUDES ******************************************************************/
11
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15
16 /* FUNCTIONS *****************************************************************/
17
18 /*
19 * @implemented
20 */
21 VOID
22 NTAPI
23 IoInitializeRemoveLockEx(IN PIO_REMOVE_LOCK RemoveLock,
24 IN ULONG AllocateTag,
25 IN ULONG MaxLockedMinutes,
26 IN ULONG HighWatermark,
27 IN ULONG RemlockSize)
28 {
29 PEXTENDED_IO_REMOVE_LOCK Lock = (PEXTENDED_IO_REMOVE_LOCK)RemoveLock;
30 PAGED_CODE();
31
32 /* Check if this is a debug lock */
33 if (RemlockSize == sizeof(IO_REMOVE_LOCK_DBG_BLOCK))
34 {
35 /* Clear the lock */
36 RtlZeroMemory(Lock, RemlockSize);
37
38 /* Setup debug parameters */
39 Lock->Dbg.HighWatermark = HighWatermark;
40 Lock->Dbg.MaxLockedTicks = MaxLockedMinutes * 600000000;
41 Lock->Dbg.AllocateTag = AllocateTag;
42 KeInitializeSpinLock(&Lock->Dbg.Spin);
43 }
44 else
45 {
46 /* Otherwise, setup a free block */
47 Lock->Common.Removed = FALSE;
48 Lock->Common.IoCount = 1;
49 KeInitializeEvent(&Lock->Common.RemoveEvent,
50 SynchronizationEvent,
51 FALSE);
52 }
53 }
54
55 /*
56 * @implemented
57 */
58 NTSTATUS
59 NTAPI
60 IoAcquireRemoveLockEx(IN PIO_REMOVE_LOCK RemoveLock,
61 IN OPTIONAL PVOID Tag,
62 IN LPCSTR File,
63 IN ULONG Line,
64 IN ULONG RemlockSize)
65 {
66 PEXTENDED_IO_REMOVE_LOCK Lock = (PEXTENDED_IO_REMOVE_LOCK)RemoveLock;
67
68 /* Increase the lock count */
69 InterlockedIncrement(&Lock->Common.IoCount);
70 if (!Lock->Common.Removed)
71 {
72 /* Check what kind of lock this is */
73 if (RemlockSize == sizeof(IO_REMOVE_LOCK_DBG_BLOCK))
74 {
75 /* FIXME: Not yet supported */
76 DPRINT1("UNIMPLEMENTED\n");
77 ASSERT(FALSE);
78 }
79 }
80 else
81 {
82 /* Otherwise, decrement the count and check if it's gone */
83 if (!InterlockedDecrement(&Lock->Common.IoCount))
84 {
85 /* Signal the event */
86 KeSetEvent(&Lock->Common.RemoveEvent, IO_NO_INCREMENT, FALSE);
87 }
88
89 /* Return pending delete */
90 return STATUS_DELETE_PENDING;
91 }
92
93 /* Otherwise, return success */
94 return STATUS_SUCCESS;
95 }
96
97 /*
98 * @implemented
99 */
100 VOID
101 NTAPI
102 IoReleaseRemoveLockEx(IN PIO_REMOVE_LOCK RemoveLock,
103 IN PVOID Tag,
104 IN ULONG RemlockSize)
105 {
106 PEXTENDED_IO_REMOVE_LOCK Lock = (PEXTENDED_IO_REMOVE_LOCK)RemoveLock;
107
108 /* Check what kind of lock this is */
109 if (RemlockSize == sizeof(IO_REMOVE_LOCK_DBG_BLOCK))
110 {
111 /* FIXME: Not yet supported */
112 DPRINT1("UNIMPLEMENTED\n");
113 ASSERT(FALSE);
114 }
115
116 /* Decrement the lock count */
117 if (!InterlockedDecrement(&Lock->Common.IoCount))
118 {
119 /* Signal the event */
120 KeSetEvent(&Lock->Common.RemoveEvent, IO_NO_INCREMENT, FALSE);
121 }
122 }
123
124 /*
125 * @implemented
126 */
127 VOID
128 NTAPI
129 IoReleaseRemoveLockAndWaitEx(IN PIO_REMOVE_LOCK RemoveLock,
130 IN PVOID Tag,
131 IN ULONG RemlockSize)
132 {
133 PEXTENDED_IO_REMOVE_LOCK Lock = (PEXTENDED_IO_REMOVE_LOCK)RemoveLock;
134 PAGED_CODE();
135
136 /* Remove the lock and decrement the count */
137 Lock->Common.Removed = TRUE;
138 if (InterlockedDecrement(&Lock->Common.IoCount) > 0)
139 {
140 /* Wait for it */
141 KeWaitForSingleObject(&Lock->Common.RemoveEvent,
142 Executive,
143 KernelMode,
144 FALSE,
145 NULL);
146 }
147
148 /* Check what kind of lock this is */
149 if (RemlockSize == sizeof(IO_REMOVE_LOCK_DBG_BLOCK))
150 {
151 /* FIXME: Not yet supported */
152 DPRINT1("UNIMPLEMENTED\n");
153 ASSERT(FALSE);
154 }
155 }
156
157 /* EOF */