Release 980215
[wine/multimedia.git] / scheduler / event.c
blobfdebbe8701d10ae3bce4584775228cab33398b81
1 /*
2 * Win32 events
4 * Copyright 1998 Alexandre Julliard
5 */
7 #include <assert.h>
8 #include "windows.h"
9 #include "winerror.h"
10 #include "k32obj.h"
11 #include "process.h"
12 #include "thread.h"
13 #include "heap.h"
15 typedef struct
17 K32OBJ header;
18 THREAD_QUEUE wait_queue;
19 BOOL32 manual_reset;
20 BOOL32 signaled;
21 } EVENT;
23 static BOOL32 EVENT_Signaled( K32OBJ *obj, DWORD thread_id );
24 static BOOL32 EVENT_Satisfied( K32OBJ *obj, DWORD thread_id );
25 static void EVENT_AddWait( K32OBJ *obj, DWORD thread_id );
26 static void EVENT_RemoveWait( K32OBJ *obj, DWORD thread_id );
27 static void EVENT_Destroy( K32OBJ *obj );
29 const K32OBJ_OPS EVENT_Ops =
31 EVENT_Signaled, /* signaled */
32 EVENT_Satisfied, /* satisfied */
33 EVENT_AddWait, /* add_wait */
34 EVENT_RemoveWait, /* remove_wait */
35 EVENT_Destroy /* destroy */
39 /***********************************************************************
40 * EVENT_Set
42 * Implementation of SetEvent. Used by ExitThread and ExitProcess.
44 void EVENT_Set( K32OBJ *obj )
46 EVENT *event = (EVENT *)obj;
47 assert( obj->type == K32OBJ_EVENT );
48 SYSTEM_LOCK();
49 event->signaled = TRUE;
50 SYNC_WakeUp( &event->wait_queue, event->manual_reset ? INFINITE32 : 1 );
51 SYSTEM_UNLOCK();
54 /***********************************************************************
55 * EVENT_Create
57 * Partial implementation of CreateEvent.
58 * Used internally by processes and threads.
60 K32OBJ *EVENT_Create( BOOL32 manual_reset, BOOL32 initial_state )
62 EVENT *event;
64 SYSTEM_LOCK();
65 if ((event = HeapAlloc( SystemHeap, 0, sizeof(*event) )))
67 event->header.type = K32OBJ_EVENT;
68 event->header.refcount = 1;
69 event->wait_queue = NULL;
70 event->manual_reset = manual_reset;
71 event->signaled = initial_state;
73 SYSTEM_UNLOCK();
74 return event ? &event->header : NULL;
78 /***********************************************************************
79 * CreateEvent32A (KERNEL32.156)
81 HANDLE32 WINAPI CreateEvent32A( SECURITY_ATTRIBUTES *sa, BOOL32 manual_reset,
82 BOOL32 initial_state, LPCSTR name )
84 HANDLE32 handle;
85 EVENT *event;
87 SYSTEM_LOCK();
88 event = (EVENT *)K32OBJ_Create( K32OBJ_EVENT, sizeof(*event),
89 name, EVENT_ALL_ACCESS, &handle );
90 if (event)
92 /* Finish initializing it */
93 event->wait_queue = NULL;
94 event->manual_reset = manual_reset;
95 event->signaled = initial_state;
96 K32OBJ_DecCount( &event->header );
98 SYSTEM_UNLOCK();
99 return handle;
103 /***********************************************************************
104 * CreateEvent32W (KERNEL32.157)
106 HANDLE32 WINAPI CreateEvent32W( SECURITY_ATTRIBUTES *sa, BOOL32 manual_reset,
107 BOOL32 initial_state, LPCWSTR name )
109 LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
110 HANDLE32 ret = CreateEvent32A( sa, manual_reset, initial_state, nameA );
111 if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
112 return ret;
116 /***********************************************************************
117 * OpenEvent32A (KERNEL32.536)
119 HANDLE32 WINAPI OpenEvent32A( DWORD access, BOOL32 inherit, LPCSTR name )
121 HANDLE32 handle = 0;
122 K32OBJ *obj;
123 SYSTEM_LOCK();
124 if ((obj = K32OBJ_FindNameType( name, K32OBJ_EVENT )) != NULL)
126 handle = HANDLE_Alloc( obj, access, inherit );
127 K32OBJ_DecCount( obj );
129 SYSTEM_UNLOCK();
130 return handle;
134 /***********************************************************************
135 * OpenEvent32W (KERNEL32.537)
137 HANDLE32 WINAPI OpenEvent32W( DWORD access, BOOL32 inherit, LPCWSTR name )
139 LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
140 HANDLE32 ret = OpenEvent32A( access, inherit, nameA );
141 if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
142 return ret;
146 /***********************************************************************
147 * PulseEvent (KERNEL32.557)
149 BOOL32 WINAPI PulseEvent( HANDLE32 handle )
151 EVENT *event;
152 SYSTEM_LOCK();
153 if (!(event = (EVENT *)HANDLE_GetObjPtr( handle, K32OBJ_EVENT,
154 EVENT_MODIFY_STATE )))
156 SYSTEM_UNLOCK();
157 return FALSE;
159 event->signaled = TRUE;
160 SYNC_WakeUp( &event->wait_queue, event->manual_reset ? INFINITE32 : 1 );
161 event->signaled = FALSE;
162 K32OBJ_DecCount( &event->header );
163 SYSTEM_UNLOCK();
164 return TRUE;
168 /***********************************************************************
169 * SetEvent (KERNEL32.644)
171 BOOL32 WINAPI SetEvent( HANDLE32 handle )
173 EVENT *event;
174 SYSTEM_LOCK();
175 if (!(event = (EVENT *)HANDLE_GetObjPtr( handle, K32OBJ_EVENT,
176 EVENT_MODIFY_STATE )))
178 SYSTEM_UNLOCK();
179 return FALSE;
181 event->signaled = TRUE;
182 SYNC_WakeUp( &event->wait_queue, event->manual_reset ? INFINITE32 : 1 );
183 K32OBJ_DecCount( &event->header );
184 SYSTEM_UNLOCK();
185 return TRUE;
189 /***********************************************************************
190 * ResetEvent (KERNEL32.586)
192 BOOL32 WINAPI ResetEvent( HANDLE32 handle )
194 EVENT *event;
195 SYSTEM_LOCK();
196 if (!(event = (EVENT *)HANDLE_GetObjPtr( handle, K32OBJ_EVENT,
197 EVENT_MODIFY_STATE )))
199 SYSTEM_UNLOCK();
200 return FALSE;
202 event->signaled = FALSE;
203 K32OBJ_DecCount( &event->header );
204 SYSTEM_UNLOCK();
205 return TRUE;
209 /***********************************************************************
210 * EVENT_Signaled
212 static BOOL32 EVENT_Signaled( K32OBJ *obj, DWORD thread_id )
214 EVENT *event = (EVENT *)obj;
215 assert( obj->type == K32OBJ_EVENT );
216 return event->signaled;
220 /***********************************************************************
221 * EVENT_Satisfied
223 * Wait on this object has been satisfied.
225 static BOOL32 EVENT_Satisfied( K32OBJ *obj, DWORD thread_id )
227 EVENT *event = (EVENT *)obj;
228 assert( obj->type == K32OBJ_EVENT );
229 /* Reset if it's an auto-reset event */
230 if (!event->manual_reset) event->signaled = FALSE;
231 return FALSE; /* Not abandoned */
235 /***********************************************************************
236 * EVENT_AddWait
238 * Add thread to object wait queue.
240 static void EVENT_AddWait( K32OBJ *obj, DWORD thread_id )
242 EVENT *event = (EVENT *)obj;
243 assert( obj->type == K32OBJ_EVENT );
244 THREAD_AddQueue( &event->wait_queue, THREAD_ID_TO_THDB(thread_id) );
248 /***********************************************************************
249 * EVENT_RemoveWait
251 * Remove thread from object wait queue.
253 static void EVENT_RemoveWait( K32OBJ *obj, DWORD thread_id )
255 EVENT *event = (EVENT *)obj;
256 assert( obj->type == K32OBJ_EVENT );
257 THREAD_RemoveQueue( &event->wait_queue, THREAD_ID_TO_THDB(thread_id) );
261 /***********************************************************************
262 * EVENT_Destroy
264 static void EVENT_Destroy( K32OBJ *obj )
266 EVENT *event = (EVENT *)obj;
267 assert( obj->type == K32OBJ_EVENT );
268 /* There cannot be any thread on the list since the ref count is 0 */
269 assert( event->wait_queue == NULL );
270 obj->type = K32OBJ_UNKNOWN;
271 HeapFree( SystemHeap, 0, event );