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
);