4 * Copyright 1998 Alexandre Julliard
15 #include "server/request.h"
21 THREAD_QUEUE wait_queue
;
26 static BOOL32
EVENT_Signaled( K32OBJ
*obj
, DWORD thread_id
);
27 static BOOL32
EVENT_Satisfied( K32OBJ
*obj
, DWORD thread_id
);
28 static void EVENT_AddWait( K32OBJ
*obj
, DWORD thread_id
);
29 static void EVENT_RemoveWait( K32OBJ
*obj
, DWORD thread_id
);
30 static void EVENT_Destroy( K32OBJ
*obj
);
32 const K32OBJ_OPS EVENT_Ops
=
34 EVENT_Signaled
, /* signaled */
35 EVENT_Satisfied
, /* satisfied */
36 EVENT_AddWait
, /* add_wait */
37 EVENT_RemoveWait
, /* remove_wait */
40 EVENT_Destroy
/* destroy */
44 /***********************************************************************
47 * Implementation of SetEvent. Used by ExitThread and ExitProcess.
49 void EVENT_Set( K32OBJ
*obj
)
51 EVENT
*event
= (EVENT
*)obj
;
52 assert( obj
->type
== K32OBJ_EVENT
);
54 event
->signaled
= TRUE
;
55 SYNC_WakeUp( &event
->wait_queue
, event
->manual_reset
? INFINITE32
: 1 );
59 /***********************************************************************
62 * Partial implementation of CreateEvent.
63 * Used internally by processes and threads.
65 K32OBJ
*EVENT_Create( BOOL32 manual_reset
, BOOL32 initial_state
)
70 if ((event
= HeapAlloc( SystemHeap
, 0, sizeof(*event
) )))
72 event
->header
.type
= K32OBJ_EVENT
;
73 event
->header
.refcount
= 1;
74 event
->wait_queue
= NULL
;
75 event
->manual_reset
= manual_reset
;
76 event
->signaled
= initial_state
;
79 return event
? &event
->header
: NULL
;
83 /***********************************************************************
84 * CreateEvent32A (KERNEL32.156)
86 HANDLE32 WINAPI
CreateEvent32A( SECURITY_ATTRIBUTES
*sa
, BOOL32 manual_reset
,
87 BOOL32 initial_state
, LPCSTR name
)
89 struct create_event_request req
;
90 struct create_event_reply reply
;
91 int len
= name
? strlen(name
) + 1 : 0;
95 req
.manual_reset
= manual_reset
;
96 req
.initial_state
= initial_state
;
97 req
.inherit
= (sa
&& (sa
->nLength
>=sizeof(*sa
)) && sa
->bInheritHandle
);
99 CLIENT_SendRequest( REQ_CREATE_EVENT
, -1, 2, &req
, sizeof(req
), name
, len
);
100 CLIENT_WaitReply( &len
, NULL
, 1, &reply
, sizeof(reply
) );
101 CHECK_LEN( len
, sizeof(reply
) );
102 if (reply
.handle
== -1) return NULL
;
105 event
= (EVENT
*)K32OBJ_Create( K32OBJ_EVENT
, sizeof(*event
), name
,
106 reply
.handle
, EVENT_ALL_ACCESS
, sa
, &handle
);
109 /* Finish initializing it */
110 event
->wait_queue
= NULL
;
111 event
->manual_reset
= manual_reset
;
112 event
->signaled
= initial_state
;
113 K32OBJ_DecCount( &event
->header
);
120 /***********************************************************************
121 * CreateEvent32W (KERNEL32.157)
123 HANDLE32 WINAPI
CreateEvent32W( SECURITY_ATTRIBUTES
*sa
, BOOL32 manual_reset
,
124 BOOL32 initial_state
, LPCWSTR name
)
126 LPSTR nameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, name
);
127 HANDLE32 ret
= CreateEvent32A( sa
, manual_reset
, initial_state
, nameA
);
128 if (nameA
) HeapFree( GetProcessHeap(), 0, nameA
);
132 /***********************************************************************
133 * WIN16_CreateEvent (KERNEL.457)
135 HANDLE32 WINAPI
WIN16_CreateEvent( BOOL32 manual_reset
, BOOL32 initial_state
)
137 return CreateEvent32A( NULL
, manual_reset
, initial_state
, NULL
);
141 /***********************************************************************
142 * OpenEvent32A (KERNEL32.536)
144 HANDLE32 WINAPI
OpenEvent32A( DWORD access
, BOOL32 inherit
, LPCSTR name
)
149 if ((obj
= K32OBJ_FindNameType( name
, K32OBJ_EVENT
)) != NULL
)
151 handle
= HANDLE_Alloc( PROCESS_Current(), obj
, access
, inherit
, -1 );
152 K32OBJ_DecCount( obj
);
159 /***********************************************************************
160 * OpenEvent32W (KERNEL32.537)
162 HANDLE32 WINAPI
OpenEvent32W( DWORD access
, BOOL32 inherit
, LPCWSTR name
)
164 LPSTR nameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, name
);
165 HANDLE32 ret
= OpenEvent32A( access
, inherit
, nameA
);
166 if (nameA
) HeapFree( GetProcessHeap(), 0, nameA
);
171 /***********************************************************************
172 * PulseEvent (KERNEL32.557)
174 BOOL32 WINAPI
PulseEvent( HANDLE32 handle
)
176 struct event_op_request req
;
179 if (!(event
= (EVENT
*)HANDLE_GetObjPtr(PROCESS_Current(), handle
,
180 K32OBJ_EVENT
, EVENT_MODIFY_STATE
,
186 if (req
.handle
!= -1)
189 req
.op
= PULSE_EVENT
;
190 CLIENT_SendRequest( REQ_EVENT_OP
, -1, 1, &req
, sizeof(req
) );
191 return !CLIENT_WaitReply( NULL
, NULL
, 0 );
193 event
->signaled
= TRUE
;
194 SYNC_WakeUp( &event
->wait_queue
, event
->manual_reset
? INFINITE32
: 1 );
195 event
->signaled
= FALSE
;
196 K32OBJ_DecCount( &event
->header
);
202 /***********************************************************************
203 * SetEvent (KERNEL32.644)
205 BOOL32 WINAPI
SetEvent( HANDLE32 handle
)
207 struct event_op_request req
;
210 if (!(event
= (EVENT
*)HANDLE_GetObjPtr(PROCESS_Current(), handle
,
211 K32OBJ_EVENT
, EVENT_MODIFY_STATE
,
217 if (req
.handle
!= -1)
221 CLIENT_SendRequest( REQ_EVENT_OP
, -1, 1, &req
, sizeof(req
) );
222 return !CLIENT_WaitReply( NULL
, NULL
, 0 );
224 event
->signaled
= TRUE
;
225 SYNC_WakeUp( &event
->wait_queue
, event
->manual_reset
? INFINITE32
: 1 );
226 K32OBJ_DecCount( &event
->header
);
232 /***********************************************************************
233 * ResetEvent (KERNEL32.586)
235 BOOL32 WINAPI
ResetEvent( HANDLE32 handle
)
237 struct event_op_request req
;
240 if (!(event
= (EVENT
*)HANDLE_GetObjPtr(PROCESS_Current(), handle
,
241 K32OBJ_EVENT
, EVENT_MODIFY_STATE
,
247 if (req
.handle
!= -1)
250 req
.op
= RESET_EVENT
;
251 CLIENT_SendRequest( REQ_EVENT_OP
, -1, 1, &req
, sizeof(req
) );
252 return !CLIENT_WaitReply( NULL
, NULL
, 0 );
254 event
->signaled
= FALSE
;
255 K32OBJ_DecCount( &event
->header
);
261 /***********************************************************************
264 static BOOL32
EVENT_Signaled( K32OBJ
*obj
, DWORD thread_id
)
266 EVENT
*event
= (EVENT
*)obj
;
267 assert( obj
->type
== K32OBJ_EVENT
);
268 return event
->signaled
;
272 /***********************************************************************
275 * Wait on this object has been satisfied.
277 static BOOL32
EVENT_Satisfied( K32OBJ
*obj
, DWORD thread_id
)
279 EVENT
*event
= (EVENT
*)obj
;
280 assert( obj
->type
== K32OBJ_EVENT
);
281 /* Reset if it's an auto-reset event */
282 if (!event
->manual_reset
) event
->signaled
= FALSE
;
283 return FALSE
; /* Not abandoned */
287 /***********************************************************************
290 * Add thread to object wait queue.
292 static void EVENT_AddWait( K32OBJ
*obj
, DWORD thread_id
)
294 EVENT
*event
= (EVENT
*)obj
;
295 assert( obj
->type
== K32OBJ_EVENT
);
296 THREAD_AddQueue( &event
->wait_queue
, THREAD_ID_TO_THDB(thread_id
) );
300 /***********************************************************************
303 * Remove thread from object wait queue.
305 static void EVENT_RemoveWait( K32OBJ
*obj
, DWORD thread_id
)
307 EVENT
*event
= (EVENT
*)obj
;
308 assert( obj
->type
== K32OBJ_EVENT
);
309 THREAD_RemoveQueue( &event
->wait_queue
, THREAD_ID_TO_THDB(thread_id
) );
313 /***********************************************************************
316 static void EVENT_Destroy( K32OBJ
*obj
)
318 EVENT
*event
= (EVENT
*)obj
;
319 assert( obj
->type
== K32OBJ_EVENT
);
320 /* There cannot be any thread on the list since the ref count is 0 */
321 assert( event
->wait_queue
== NULL
);
322 obj
->type
= K32OBJ_UNKNOWN
;
323 HeapFree( SystemHeap
, 0, event
);
329 /***********************************************************************
330 * NOTE: The Win95 VWin32_Event routines given below are really low-level
331 * routines implemented directly by VWin32. The user-mode libraries
332 * implement Win32 synchronisation routines on top of these low-level
333 * primitives. We do it the other way around here :-)
336 /***********************************************************************
337 * VWin32_EventCreate (KERNEL.442)
339 HANDLE32 WINAPI
VWin32_EventCreate(VOID
)
341 HANDLE32 hEvent
= CreateEvent32A( NULL
, FALSE
, 0, NULL
);
342 return ConvertToGlobalHandle( hEvent
);
345 /***********************************************************************
346 * VWin32_EventDestroy (KERNEL.443)
348 VOID WINAPI
VWin32_EventDestroy(HANDLE32 event
)
350 CloseHandle( event
);
353 /***********************************************************************
354 * VWin32_EventWait (KERNEL.450)
356 VOID WINAPI
VWin32_EventWait(HANDLE32 event
)
358 SYSLEVEL_ReleaseWin16Lock();
359 WaitForSingleObject( event
, INFINITE32
);
360 SYSLEVEL_RestoreWin16Lock();
363 /***********************************************************************
364 * VWin32_EventSet (KERNEL.451)
366 VOID WINAPI
VWin32_EventSet(HANDLE32 event
)