- fixed missing stdlib.h and string.h includes everywhere
[wine] / scheduler / event.c
1 /*
2  * Win32 events
3  *
4  * Copyright 1998 Alexandre Julliard
5  */
6
7 #include <assert.h>
8 #include <string.h>
9 #include "winerror.h"
10 #include "k32obj.h"
11 #include "process.h"
12 #include "thread.h"
13 #include "heap.h"
14 #include "syslevel.h"
15 #include "server/request.h"
16 #include "server.h"
17
18 typedef struct
19 {
20     K32OBJ        header;
21 } EVENT;
22
23
24 /***********************************************************************
25  *           CreateEvent32A    (KERNEL32.156)
26  */
27 HANDLE WINAPI CreateEventA( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
28                                 BOOL initial_state, LPCSTR name )
29 {
30     struct create_event_request req;
31     struct create_event_reply reply;
32     int len = name ? strlen(name) + 1 : 0;
33     HANDLE handle;
34     EVENT *event;
35
36     req.manual_reset = manual_reset;
37     req.initial_state = initial_state;
38     req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
39
40     CLIENT_SendRequest( REQ_CREATE_EVENT, -1, 2, &req, sizeof(req), name, len );
41     CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
42     if (reply.handle == -1) return 0;
43
44     SYSTEM_LOCK();
45     event = (EVENT *)K32OBJ_Create( K32OBJ_EVENT, sizeof(*event), name,
46                                     reply.handle, EVENT_ALL_ACCESS, sa, &handle );
47     if (event)
48         K32OBJ_DecCount( &event->header );
49     SYSTEM_UNLOCK();
50     if (handle == INVALID_HANDLE_VALUE) handle = 0;
51     return handle;
52 }
53
54
55 /***********************************************************************
56  *           CreateEvent32W    (KERNEL32.157)
57  */
58 HANDLE WINAPI CreateEventW( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
59                                 BOOL initial_state, LPCWSTR name )
60 {
61     LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
62     HANDLE ret = CreateEventA( sa, manual_reset, initial_state, nameA );
63     if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
64     return ret;
65 }
66
67 /***********************************************************************
68  *           WIN16_CreateEvent    (KERNEL.457)
69  */
70 HANDLE WINAPI WIN16_CreateEvent( BOOL manual_reset, BOOL initial_state )
71 {
72     return CreateEventA( NULL, manual_reset, initial_state, NULL );
73 }
74
75
76 /***********************************************************************
77  *           OpenEvent32A    (KERNEL32.536)
78  */
79 HANDLE WINAPI OpenEventA( DWORD access, BOOL inherit, LPCSTR name )
80 {
81     HANDLE handle = 0;
82     K32OBJ *obj;
83     struct open_named_obj_request req;
84     struct open_named_obj_reply reply;
85     int len = name ? strlen(name) + 1 : 0;
86
87     req.type    = OPEN_EVENT;
88     req.access  = access;
89     req.inherit = inherit;
90     CLIENT_SendRequest( REQ_OPEN_NAMED_OBJ, -1, 2, &req, sizeof(req), name, len );
91     CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
92     if (reply.handle != -1)
93     {
94         SYSTEM_LOCK();
95         if ((obj = K32OBJ_FindNameType( name, K32OBJ_EVENT )) != NULL)
96         {
97             handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, reply.handle );
98             K32OBJ_DecCount( obj );
99             if (handle == INVALID_HANDLE_VALUE)
100                 handle = 0; /* must return 0 on failure, not -1 */
101         }
102         else CLIENT_CloseHandle( reply.handle );
103         SYSTEM_UNLOCK();
104     }
105     return handle;
106 }
107
108
109 /***********************************************************************
110  *           OpenEvent32W    (KERNEL32.537)
111  */
112 HANDLE WINAPI OpenEventW( DWORD access, BOOL inherit, LPCWSTR name )
113 {
114     LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
115     HANDLE ret = OpenEventA( access, inherit, nameA );
116     if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
117     return ret;
118 }
119
120
121 /***********************************************************************
122  *           EVENT_Operation
123  *
124  * Execute an event operation (set,reset,pulse).
125  */
126 static BOOL EVENT_Operation( HANDLE handle, enum event_op op )
127 {
128     struct event_op_request req;
129
130     req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
131                                          K32OBJ_EVENT, EVENT_MODIFY_STATE );
132     if (req.handle == -1) return FALSE;
133     req.op = op;
134     CLIENT_SendRequest( REQ_EVENT_OP, -1, 1, &req, sizeof(req) );
135     return !CLIENT_WaitReply( NULL, NULL, 0 );
136 }
137
138
139 /***********************************************************************
140  *           PulseEvent    (KERNEL32.557)
141  */
142 BOOL WINAPI PulseEvent( HANDLE handle )
143 {
144     return EVENT_Operation( handle, PULSE_EVENT );
145 }
146
147
148 /***********************************************************************
149  *           SetEvent    (KERNEL32.644)
150  */
151 BOOL WINAPI SetEvent( HANDLE handle )
152 {
153     return EVENT_Operation( handle, SET_EVENT );
154 }
155
156
157 /***********************************************************************
158  *           ResetEvent    (KERNEL32.586)
159  */
160 BOOL WINAPI ResetEvent( HANDLE handle )
161 {
162     return EVENT_Operation( handle, RESET_EVENT );
163 }
164
165
166 /***********************************************************************
167  * NOTE: The Win95 VWin32_Event routines given below are really low-level
168  *       routines implemented directly by VWin32. The user-mode libraries
169  *       implement Win32 synchronisation routines on top of these low-level
170  *       primitives. We do it the other way around here :-)
171  */
172
173 /***********************************************************************
174  *       VWin32_EventCreate     (KERNEL.442)
175  */
176 HANDLE WINAPI VWin32_EventCreate(VOID)
177 {
178     HANDLE hEvent = CreateEventA( NULL, FALSE, 0, NULL );
179     return ConvertToGlobalHandle( hEvent );
180 }
181
182 /***********************************************************************
183  *       VWin32_EventDestroy    (KERNEL.443)
184  */
185 VOID WINAPI VWin32_EventDestroy(HANDLE event)
186 {
187     CloseHandle( event );
188 }
189
190 /***********************************************************************
191  *       VWin32_EventWait       (KERNEL.450) 
192  */
193 VOID WINAPI VWin32_EventWait(HANDLE event)
194 {
195     SYSLEVEL_ReleaseWin16Lock();
196     WaitForSingleObject( event, INFINITE );
197     SYSLEVEL_RestoreWin16Lock();
198 }
199
200 /***********************************************************************
201  *       VWin32_EventSet        (KERNEL.451)
202  */
203 VOID WINAPI VWin32_EventSet(HANDLE event)
204 {
205     SetEvent( event );
206 }
207