Reimplemented dispatcher database lock and synchronization primitives.
[reactos.git] / reactos / ntoskrnl / ke / event.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ke/event.c
5 * PURPOSE: Implements events
6 * PROGRAMMER: David Welch (welch@mcmail.com)
7 * UPDATE HISTORY:
8 * Created 22/05/98
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ddk/ntddk.h>
14 #include <internal/ke.h>
15 #include <internal/id.h>
16 #include <internal/ps.h>
17
18 #define NDEBUG
19 #include <internal/debug.h>
20
21 /* FUNCTIONS ****************************************************************/
22
23 /*
24 * @implemented
25 */
26 VOID STDCALL KeClearEvent (PKEVENT Event)
27 {
28 DPRINT("KeClearEvent(Event %x)\n", Event);
29 Event->Header.SignalState = FALSE;
30 }
31
32 /*
33 * @implemented
34 */
35 VOID STDCALL KeInitializeEvent (PKEVENT Event,
36 EVENT_TYPE Type,
37 BOOLEAN State)
38 {
39 ULONG IType;
40
41 if (Type == NotificationEvent)
42 {
43 IType = InternalNotificationEvent;
44 }
45 else if (Type == SynchronizationEvent)
46 {
47 IType = InternalSynchronizationEvent;
48 }
49 else
50 {
51 assert(FALSE);
52 return;
53 }
54
55 KeInitializeDispatcherHeader(&(Event->Header),
56 IType,
57 sizeof(Event)/sizeof(ULONG),State);
58 InitializeListHead(&(Event->Header.WaitListHead));
59 }
60
61 /*
62 * @implemented
63 */
64 LONG STDCALL KeReadStateEvent (PKEVENT Event)
65 {
66 return(Event->Header.SignalState);
67 }
68
69 /*
70 * @implemented
71 */
72 LONG STDCALL KeResetEvent (PKEVENT Event)
73 {
74 return(InterlockedExchange(&(Event->Header.SignalState),0));
75 }
76
77 /*
78 * @implemented
79 */
80 LONG STDCALL KeSetEvent (PKEVENT Event,
81 KPRIORITY Increment,
82 BOOLEAN Wait)
83 {
84 KIRQL OldIrql;
85 int ret;
86
87 DPRINT("KeSetEvent(Event %x, Wait %x)\n",Event,Wait);
88
89 OldIrql = KeAcquireDispatcherDatabaseLock();
90
91 ret = InterlockedExchange(&(Event->Header.SignalState),1);
92
93 KeDispatcherObjectWake((DISPATCHER_HEADER *)Event);
94
95 if (Wait == FALSE)
96 {
97 KeReleaseDispatcherDatabaseLock(OldIrql);
98 }
99 else
100 {
101 KTHREAD *Thread = KeGetCurrentThread();
102 Thread->WaitNext = Wait;
103 Thread->WaitIrql = OldIrql;
104 }
105
106 return(ret);
107 }
108
109 /*
110 * @implemented
111 */
112 NTSTATUS STDCALL KePulseEvent (PKEVENT Event,
113 KPRIORITY Increment,
114 BOOLEAN Wait)
115 {
116 KIRQL OldIrql;
117 int ret;
118
119 DPRINT("KePulseEvent(Event %x, Wait %x)\n",Event,Wait);
120 OldIrql = KeAcquireDispatcherDatabaseLock();
121 ret = InterlockedExchange(&(Event->Header.SignalState),1);
122 KeDispatcherObjectWake((DISPATCHER_HEADER *)Event);
123 InterlockedExchange(&(Event->Header.SignalState),0);
124
125 if (Wait == FALSE)
126 {
127 KeReleaseDispatcherDatabaseLock(OldIrql);
128 }
129 else
130 {
131 KTHREAD *Thread = KeGetCurrentThread();
132 Thread->WaitNext = Wait;
133 Thread->WaitIrql = OldIrql;
134 }
135
136 return ((NTSTATUS)ret);
137 }
138
139 /* EOF */