4 * Copyright 1998 Alexandre Julliard
18 THREAD_QUEUE wait_queue;
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 /***********************************************************************
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 );
49 event->signaled = TRUE;
50 SYNC_WakeUp( &event->wait_queue, event->manual_reset ? INFINITE32 : 1 );
54 /***********************************************************************
57 * Partial implementation of CreateEvent.
58 * Used internally by processes and threads.
60 K32OBJ *EVENT_Create( BOOL32 manual_reset, BOOL32 initial_state )
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;
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 )
88 event = (EVENT *)K32OBJ_Create( K32OBJ_EVENT, sizeof(*event),
89 name, EVENT_ALL_ACCESS, &handle );
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 );
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 );
116 /***********************************************************************
117 * OpenEvent32A (KERNEL32.536)
119 HANDLE32 WINAPI OpenEvent32A( DWORD access, BOOL32 inherit, LPCSTR name )
124 if ((obj = K32OBJ_FindNameType( name, K32OBJ_EVENT )) != NULL)
126 handle = HANDLE_Alloc( obj, access, inherit );
127 K32OBJ_DecCount( obj );
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 );
146 /***********************************************************************
147 * PulseEvent (KERNEL32.557)
149 BOOL32 WINAPI PulseEvent( HANDLE32 handle )
153 if (!(event = (EVENT *)HANDLE_GetObjPtr( handle, K32OBJ_EVENT,
154 EVENT_MODIFY_STATE )))
159 event->signaled = TRUE;
160 SYNC_WakeUp( &event->wait_queue, event->manual_reset ? INFINITE32 : 1 );
161 event->signaled = FALSE;
162 K32OBJ_DecCount( &event->header );
168 /***********************************************************************
169 * SetEvent (KERNEL32.644)
171 BOOL32 WINAPI SetEvent( HANDLE32 handle )
175 if (!(event = (EVENT *)HANDLE_GetObjPtr( handle, K32OBJ_EVENT,
176 EVENT_MODIFY_STATE )))
181 event->signaled = TRUE;
182 SYNC_WakeUp( &event->wait_queue, event->manual_reset ? INFINITE32 : 1 );
183 K32OBJ_DecCount( &event->header );
189 /***********************************************************************
190 * ResetEvent (KERNEL32.586)
192 BOOL32 WINAPI ResetEvent( HANDLE32 handle )
196 if (!(event = (EVENT *)HANDLE_GetObjPtr( handle, K32OBJ_EVENT,
197 EVENT_MODIFY_STATE )))
202 event->signaled = FALSE;
203 K32OBJ_DecCount( &event->header );
209 /***********************************************************************
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 /***********************************************************************
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 /***********************************************************************
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 /***********************************************************************
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 /***********************************************************************
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 );