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 */
37 EVENT_Destroy
/* destroy */
41 /***********************************************************************
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
);
51 event
->signaled
= TRUE
;
52 SYNC_WakeUp( &event
->wait_queue
, event
->manual_reset
? INFINITE32
: 1 );
56 /***********************************************************************
59 * Partial implementation of CreateEvent.
60 * Used internally by processes and threads.
62 K32OBJ
*EVENT_Create( BOOL32 manual_reset
, BOOL32 initial_state
)
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
;
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
)
90 event
= (EVENT
*)K32OBJ_Create( K32OBJ_EVENT
, sizeof(*event
),
91 name
, EVENT_ALL_ACCESS
, sa
, &handle
);
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
);
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
);
118 /***********************************************************************
119 * OpenEvent32A (KERNEL32.536)
121 HANDLE32 WINAPI
OpenEvent32A( DWORD access
, BOOL32 inherit
, LPCSTR name
)
126 if ((obj
= K32OBJ_FindNameType( name
, K32OBJ_EVENT
)) != NULL
)
128 handle
= HANDLE_Alloc( PROCESS_Current(), obj
, access
, inherit
, -1 );
129 K32OBJ_DecCount( obj
);
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
);
148 /***********************************************************************
149 * PulseEvent (KERNEL32.557)
151 BOOL32 WINAPI
PulseEvent( HANDLE32 handle
)
155 if (!(event
= (EVENT
*)HANDLE_GetObjPtr(PROCESS_Current(), handle
,
156 K32OBJ_EVENT
, EVENT_MODIFY_STATE
, NULL
)))
161 event
->signaled
= TRUE
;
162 SYNC_WakeUp( &event
->wait_queue
, event
->manual_reset
? INFINITE32
: 1 );
163 event
->signaled
= FALSE
;
164 K32OBJ_DecCount( &event
->header
);
170 /***********************************************************************
171 * SetEvent (KERNEL32.644)
173 BOOL32 WINAPI
SetEvent( HANDLE32 handle
)
177 if (!(event
= (EVENT
*)HANDLE_GetObjPtr(PROCESS_Current(), handle
,
178 K32OBJ_EVENT
, EVENT_MODIFY_STATE
, NULL
)))
183 event
->signaled
= TRUE
;
184 SYNC_WakeUp( &event
->wait_queue
, event
->manual_reset
? INFINITE32
: 1 );
185 K32OBJ_DecCount( &event
->header
);
191 /***********************************************************************
192 * ResetEvent (KERNEL32.586)
194 BOOL32 WINAPI
ResetEvent( HANDLE32 handle
)
198 if (!(event
= (EVENT
*)HANDLE_GetObjPtr(PROCESS_Current(), handle
,
199 K32OBJ_EVENT
, EVENT_MODIFY_STATE
, NULL
)))
204 event
->signaled
= FALSE
;
205 K32OBJ_DecCount( &event
->header
);
211 /***********************************************************************
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 /***********************************************************************
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 /***********************************************************************
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 /***********************************************************************
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 /***********************************************************************
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
);