Release 980712
[wine/multimedia.git] / scheduler / event.c
blobd5ad9c814b26046305ab922429f3404897af95e4
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 NULL, /* read */
36 NULL, /* write */
37 EVENT_Destroy /* destroy */
41 /***********************************************************************
42 * EVENT_Set
44 * Implementation of SetEvent. Used by ExitThread and ExitProcess.
46 void EVENT_Set( K32OBJ *obj )
48 EVENT *event = (EVENT *)obj;
49 assert( obj->type == K32OBJ_EVENT );
50 SYSTEM_LOCK();
51 event->signaled = TRUE;
52 SYNC_WakeUp( &event->wait_queue, event->manual_reset ? INFINITE32 : 1 );
53 SYSTEM_UNLOCK();
56 /***********************************************************************
57 * EVENT_Create
59 * Partial implementation of CreateEvent.
60 * Used internally by processes and threads.
62 K32OBJ *EVENT_Create( BOOL32 manual_reset, BOOL32 initial_state )
64 EVENT *event;
66 SYSTEM_LOCK();
67 if ((event = HeapAlloc( SystemHeap, 0, sizeof(*event) )))
69 event->header.type = K32OBJ_EVENT;
70 event->header.refcount = 1;
71 event->wait_queue = NULL;
72 event->manual_reset = manual_reset;
73 event->signaled = initial_state;
75 SYSTEM_UNLOCK();
76 return event ? &event->header : NULL;
80 /***********************************************************************
81 * CreateEvent32A (KERNEL32.156)
83 HANDLE32 WINAPI CreateEvent32A( SECURITY_ATTRIBUTES *sa, BOOL32 manual_reset,
84 BOOL32 initial_state, LPCSTR name )
86 HANDLE32 handle;
87 EVENT *event;
89 SYSTEM_LOCK();
90 event = (EVENT *)K32OBJ_Create( K32OBJ_EVENT, sizeof(*event),
91 name, EVENT_ALL_ACCESS, sa, &handle );
92 if (event)
94 /* Finish initializing it */
95 event->wait_queue = NULL;
96 event->manual_reset = manual_reset;
97 event->signaled = initial_state;
98 K32OBJ_DecCount( &event->header );
100 SYSTEM_UNLOCK();
101 return handle;
105 /***********************************************************************
106 * CreateEvent32W (KERNEL32.157)
108 HANDLE32 WINAPI CreateEvent32W( SECURITY_ATTRIBUTES *sa, BOOL32 manual_reset,
109 BOOL32 initial_state, LPCWSTR name )
111 LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
112 HANDLE32 ret = CreateEvent32A( sa, manual_reset, initial_state, nameA );
113 if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
114 return ret;
118 /***********************************************************************
119 * OpenEvent32A (KERNEL32.536)
121 HANDLE32 WINAPI OpenEvent32A( DWORD access, BOOL32 inherit, LPCSTR name )
123 HANDLE32 handle = 0;
124 K32OBJ *obj;
125 SYSTEM_LOCK();
126 if ((obj = K32OBJ_FindNameType( name, K32OBJ_EVENT )) != NULL)
128 handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit );
129 K32OBJ_DecCount( obj );
131 SYSTEM_UNLOCK();
132 return handle;
136 /***********************************************************************
137 * OpenEvent32W (KERNEL32.537)
139 HANDLE32 WINAPI OpenEvent32W( DWORD access, BOOL32 inherit, LPCWSTR name )
141 LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
142 HANDLE32 ret = OpenEvent32A( access, inherit, nameA );
143 if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
144 return ret;
148 /***********************************************************************
149 * PulseEvent (KERNEL32.557)
151 BOOL32 WINAPI PulseEvent( HANDLE32 handle )
153 EVENT *event;
154 SYSTEM_LOCK();
155 if (!(event = (EVENT *)HANDLE_GetObjPtr(PROCESS_Current(), handle,
156 K32OBJ_EVENT, EVENT_MODIFY_STATE)))
158 SYSTEM_UNLOCK();
159 return FALSE;
161 event->signaled = TRUE;
162 SYNC_WakeUp( &event->wait_queue, event->manual_reset ? INFINITE32 : 1 );
163 event->signaled = FALSE;
164 K32OBJ_DecCount( &event->header );
165 SYSTEM_UNLOCK();
166 return TRUE;
170 /***********************************************************************
171 * SetEvent (KERNEL32.644)
173 BOOL32 WINAPI SetEvent( HANDLE32 handle )
175 EVENT *event;
176 SYSTEM_LOCK();
177 if (!(event = (EVENT *)HANDLE_GetObjPtr(PROCESS_Current(), handle,
178 K32OBJ_EVENT, EVENT_MODIFY_STATE)))
180 SYSTEM_UNLOCK();
181 return FALSE;
183 event->signaled = TRUE;
184 SYNC_WakeUp( &event->wait_queue, event->manual_reset ? INFINITE32 : 1 );
185 K32OBJ_DecCount( &event->header );
186 SYSTEM_UNLOCK();
187 return TRUE;
191 /***********************************************************************
192 * ResetEvent (KERNEL32.586)
194 BOOL32 WINAPI ResetEvent( HANDLE32 handle )
196 EVENT *event;
197 SYSTEM_LOCK();
198 if (!(event = (EVENT *)HANDLE_GetObjPtr(PROCESS_Current(), handle,
199 K32OBJ_EVENT, EVENT_MODIFY_STATE)))
201 SYSTEM_UNLOCK();
202 return FALSE;
204 event->signaled = FALSE;
205 K32OBJ_DecCount( &event->header );
206 SYSTEM_UNLOCK();
207 return TRUE;
211 /***********************************************************************
212 * EVENT_Signaled
214 static BOOL32 EVENT_Signaled( K32OBJ *obj, DWORD thread_id )
216 EVENT *event = (EVENT *)obj;
217 assert( obj->type == K32OBJ_EVENT );
218 return event->signaled;
222 /***********************************************************************
223 * EVENT_Satisfied
225 * Wait on this object has been satisfied.
227 static BOOL32 EVENT_Satisfied( K32OBJ *obj, DWORD thread_id )
229 EVENT *event = (EVENT *)obj;
230 assert( obj->type == K32OBJ_EVENT );
231 /* Reset if it's an auto-reset event */
232 if (!event->manual_reset) event->signaled = FALSE;
233 return FALSE; /* Not abandoned */
237 /***********************************************************************
238 * EVENT_AddWait
240 * Add thread to object wait queue.
242 static void EVENT_AddWait( K32OBJ *obj, DWORD thread_id )
244 EVENT *event = (EVENT *)obj;
245 assert( obj->type == K32OBJ_EVENT );
246 THREAD_AddQueue( &event->wait_queue, THREAD_ID_TO_THDB(thread_id) );
250 /***********************************************************************
251 * EVENT_RemoveWait
253 * Remove thread from object wait queue.
255 static void EVENT_RemoveWait( K32OBJ *obj, DWORD thread_id )
257 EVENT *event = (EVENT *)obj;
258 assert( obj->type == K32OBJ_EVENT );
259 THREAD_RemoveQueue( &event->wait_queue, THREAD_ID_TO_THDB(thread_id) );
263 /***********************************************************************
264 * EVENT_Destroy
266 static void EVENT_Destroy( K32OBJ *obj )
268 EVENT *event = (EVENT *)obj;
269 assert( obj->type == K32OBJ_EVENT );
270 /* There cannot be any thread on the list since the ref count is 0 */
271 assert( event->wait_queue == NULL );
272 obj->type = K32OBJ_UNKNOWN;
273 HeapFree( SystemHeap, 0, event );