source: trunk/src/kernel32/hmevent.cpp@ 6084

Last change on this file since 6084 was 6084, checked in by sandervl, 24 years ago

semaphore updates

File size: 17.6 KB
Line 
1/* $Id: hmevent.cpp,v 1.8 2001-06-23 16:59:27 sandervl Exp $ */
2
3/*
4 * Win32 Event Semaphore implementation
5 *
6 * TODO: Inheritance
7 * TODO: Does DCE_POSTONE work in Warp 3 or 4 with no FP applied?
8 * TODO: No inheritance when CreateEvent is called for existing named event semaphore?
9 * (see HMCreateEvent in handlemanager.cpp)
10 * TODO: Name collisions with files & mutex not allowed. Check if this can happen in OS/2
11 *
12 * Project Odin Software License can be found in LICENSE.TXT
13 *
14 * Copyright 2001 Sander van Leeuwen (sandervl@xs4all.nl)
15 */
16
17#undef DEBUG_LOCAL
18//#define DEBUG_LOCAL
19
20
21/*****************************************************************************
22 * Remark *
23 *****************************************************************************
24
25 */
26
27
28/*****************************************************************************
29 * Includes *
30 *****************************************************************************/
31
32#ifdef USE_OS2SEMAPHORES
33#define INCL_DOSSEMAPHORES
34#define INCL_DOSERRORS
35#include <os2wrap.h>
36#include <win32type.h>
37#include <win32api.h>
38#include <winconst.h>
39#else
40#include <os2win.h>
41#endif
42
43#include <stdlib.h>
44#include <string.h>
45#include "unicode.h"
46#include "misc.h"
47
48#include "HandleManager.H"
49#include "HMEvent.h"
50#include "HMSemaphore.h"
51#include "oslibdos.h"
52
53#define DBG_LOCALLOG DBG_hmevent
54#include "dbglocal.h"
55
56#ifndef DCE_AUTORESET
57#define DCE_AUTORESET 0x1000 /* DosCreateEventSem option to auto-reset */
58 /* event semaphore on post. */
59#define DCE_POSTONE 0x0800 /* DosCreateEventSem option to post only */
60 /* waiter and auto-reset the semaphore when*/
61 /* there are multiple waiters. */
62#endif
63
64/*****************************************************************************
65 * Defines *
66 *****************************************************************************/
67
68/*****************************************************************************
69 * Structures *
70 *****************************************************************************/
71
72/*****************************************************************************
73 * Local Prototypes *
74 *****************************************************************************/
75
76
77/*****************************************************************************
78 * Name : HMCreateEvent
79 * Purpose : router function for CreateEvent
80 * Parameters:
81 * Variables :
82 * Result :
83 * Remark :
84 * Status :
85 *
86 * Author : Patrick Haller [Tue, 1999/07/06 20:44]
87 *****************************************************************************/
88
89DWORD HMDeviceEventClass::CreateEvent(PHMHANDLEDATA pHMHandleData,
90 LPSECURITY_ATTRIBUTES lpsa,
91 BOOL fManualReset,
92 BOOL fInitialState,
93 LPCTSTR lpszEventName)
94{
95#ifdef USE_OS2SEMAPHORES
96 APIRET rc;
97 HEV hev;
98 char szSemName[CCHMAXPATH];
99
100 dprintf(("KERNEL32: HandleManager::Event::CreateEvent(%08xh,%08xh,%08xh,%08xh,%s)\n",
101 pHMHandleData,
102 lpsa,
103 fManualReset,
104 fInitialState,
105 lpszEventName));
106
107 if(lpszEventName) {
108 strcpy(szSemName, "\\SEM32\\");
109 strcat(szSemName, lpszEventName);
110 lpszEventName = szSemName;
111 FixSemName((char *)lpszEventName);
112 }
113 //Manual reset means all threads waiting on the event semaphore will be
114 //unblocked and the app must manually reset the event semaphore
115 //Automatic reset -> only one waiting thread unblocked & state reset
116 rc = DosCreateEventSem(lpszEventName, &hev, (fManualReset) ? 0 : (DCE_POSTONE|DCE_AUTORESET), fInitialState);
117
118 if(rc) {
119 dprintf(("DosCreateEventSem %x failed with rc %d", pHMHandleData->hHMHandle, rc));
120 pHMHandleData->hHMHandle = 0;
121 return error2WinError(rc);
122 }
123 pHMHandleData->dwAccess = EVENT_ALL_ACCESS_W;
124 pHMHandleData->dwFlags = fManualReset;
125 pHMHandleData->hHMHandle = hev;
126 pHMHandleData->dwInternalType = HMTYPE_EVENTSEM;
127 return ERROR_SUCCESS_W;
128#else
129 HANDLE hOpen32;
130
131 dprintf(("KERNEL32: HandleManager::Event::CreateEvent(%08xh,%08xh,%08xh,%08xh,%s)\n",
132 pHMHandleData,
133 lpsa,
134 fManualReset,
135 fInitialState,
136 lpszEventName));
137
138 hOpen32 = O32_CreateEvent(lpsa, // call Open32
139 fManualReset,
140 fInitialState,
141 lpszEventName);
142
143 if (0 != hOpen32) // check success
144 {
145 pHMHandleData->hHMHandle = hOpen32; // save handle
146 return (NO_ERROR);
147 }
148 else
149 return (O32_GetLastError());
150#endif
151}
152
153
154/*****************************************************************************
155 * Name : HMOpenEvent
156 * Purpose : router function for OpenEvent
157 * Parameters:
158 * Variables :
159 * Result :
160 * Remark :
161 * Status :
162 *
163 * Author : Patrick Haller [Tue, 1999/07/06 20:44]
164 *****************************************************************************/
165
166DWORD HMDeviceEventClass::OpenEvent(PHMHANDLEDATA pHMHandleData,
167 BOOL fInheritHandle,
168 LPCTSTR lpszEventName)
169{
170#ifdef USE_OS2SEMAPHORES
171 HEV hev;
172 APIRET rc;
173 char szSemName[CCHMAXPATH];
174
175 dprintf(("KERNEL32: HandleManager::Event::OpenEvent(%08xh,%08xh,%s)\n",
176 pHMHandleData,
177 fInheritHandle,
178 lpszEventName));
179
180 if(lpszEventName == NULL) {
181 pHMHandleData->hHMHandle = 0;
182 return ERROR_INVALID_PARAMETER_W;
183 }
184
185 strcpy(szSemName, "\\SEM32\\");
186 strcat(szSemName, lpszEventName);
187 FixSemName(szSemName);
188 rc = DosOpenEventSem(szSemName, &hev);
189 if(rc) {
190 dprintf(("DosOpenEventSem %x failed with rc %d", pHMHandleData->hHMHandle, rc));
191 pHMHandleData->hHMHandle = 0;
192 return error2WinError(rc);
193 }
194 pHMHandleData->dwInternalType = HMTYPE_EVENTSEM;
195 pHMHandleData->hHMHandle = hev;
196 return ERROR_SUCCESS_W;
197#else
198 HANDLE hOpen32;
199
200 dprintf(("KERNEL32: HandleManager::Event::OpenEvent(%08xh,%08xh,%s)\n",
201 pHMHandleData,
202 fInheritHandle,
203 lpszEventName));
204
205 hOpen32 = O32_OpenEvent(pHMHandleData->dwAccess, // call Open32
206 fInheritHandle,
207 lpszEventName);
208
209 if (0 != hOpen32) // check success
210 {
211 pHMHandleData->hHMHandle = hOpen32; // save handle
212 return (NO_ERROR);
213 }
214 else
215 return (O32_GetLastError());
216#endif
217}
218
219/*****************************************************************************
220 * Name : HMDeviceEventClass::CloseHandle
221 * Purpose : close the handle
222 * Parameters: PHMHANDLEDATA pHMHandleData
223 * Variables :
224 * Result : API returncode
225 * Remark :
226 * Status :
227 *
228 * Author :
229 *****************************************************************************/
230
231#ifdef USE_OS2SEMAPHORES
232BOOL HMDeviceEventClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
233{
234 APIRET rc;
235
236 if(pHMHandleData->hHMHandle) {
237 rc = DosCloseEventSem((HEV)pHMHandleData->hHMHandle);
238 if(rc) {
239 dprintf(("DosCloseEventSem %x failed with rc %d", pHMHandleData->hHMHandle, rc));
240 SetLastError(error2WinError(rc));
241 return FALSE;
242 }
243 }
244 return TRUE;
245}
246#endif
247
248/*****************************************************************************
249 * Name : HMDeviceEventClass::DuplicateHandle
250 * Purpose :
251 * Parameters:
252 * various parameters as required
253 * Variables :
254 * Result :
255 * Remark : the standard behaviour is to return an error code for non-
256 * existant request codes
257 * Status :
258 *
259 * Author :
260 *****************************************************************************/
261#ifdef USE_OS2SEMAPHORES
262BOOL HMDeviceEventClass::DuplicateHandle(PHMHANDLEDATA pHMHandleData, HANDLE srcprocess,
263 PHMHANDLEDATA pHMSrcHandle,
264 HANDLE destprocess,
265 PHANDLE desthandle,
266 DWORD fdwAccess,
267 BOOL fInherit,
268 DWORD fdwOptions,
269 DWORD fdwOdinOptions)
270{
271 APIRET rc;
272 HEV hev;
273
274 dprintf(("KERNEL32:HandleManager::DuplicateHandle %s(%08x,%08x,%08x,%08x,%08x) - NOT IMPLEMENTED!!!!!!!!\n",
275 lpHMDeviceName,
276 pHMHandleData,
277 srcprocess, pHMSrcHandle, destprocess, desthandle));
278
279 if(srcprocess != destprocess) {
280 DebugInt3();
281 SetLastError(ERROR_ACCESS_DENIED_W);
282 return FALSE;
283 }
284 hev = (HEV)pHMSrcHandle->hHMHandle;
285 rc = DosOpenEventSem(NULL, &hev);
286 if(rc) {
287 dprintf(("DosOpenEventSem %x failed with rc %d", pHMSrcHandle->hHMHandle, rc));
288 pHMHandleData->hHMHandle = 0;
289 SetLastError(error2WinError(rc));
290 return FALSE;
291 }
292 pHMHandleData->dwAccess = fdwAccess;
293 pHMHandleData->dwFlags = pHMSrcHandle->dwFlags; //fManualReset
294 pHMHandleData->hHMHandle = hev;
295 pHMHandleData->dwInternalType = HMTYPE_EVENTSEM;
296 SetLastError(ERROR_SUCCESS_W);
297 return TRUE;
298}
299#endif
300
301#ifdef USE_OS2SEMAPHORES
302/*****************************************************************************
303 * Name : DWORD HMDeviceEventClass::WaitForSingleObject
304 * Purpose : object synchronization
305 * Parameters: PHMHANDLEDATA pHMHandleData
306 * DWORD dwTimeout
307 * Variables :
308 * Result : API returncode
309 * Remark :
310 * Status :
311 *
312 * Author : SvL
313 *****************************************************************************/
314
315DWORD HMDeviceEventClass::WaitForSingleObject(PHMHANDLEDATA pHMHandleData,
316 DWORD dwTimeout)
317{
318 DWORD rc;
319
320 dprintf2(("KERNEL32: HMDeviceEventClass::WaitForSingleObject(%08xh %08xh)",
321 pHMHandleData->hHMHandle, dwTimeout));
322
323 if(!(pHMHandleData->dwAccess & SYNCHRONIZE_W) )
324 {
325 dprintf(("ERROR: Access denied!!"));
326 SetLastError(ERROR_ACCESS_DENIED_W);
327 return WAIT_FAILED_W;
328 }
329
330 rc = DosWaitEventSem(pHMHandleData->hHMHandle, dwTimeout);
331 if(rc && rc != ERROR_INTERRUPT && rc != ERROR_TIMEOUT && rc != ERROR_SEM_OWNER_DIED) {
332 dprintf(("DosWaitEventSem %x failed with rc %d", pHMHandleData->hHMHandle, rc));
333 SetLastError(error2WinError(rc));
334 return WAIT_FAILED_W;
335 }
336 SetLastError(ERROR_SUCCESS_W);
337 if(rc == ERROR_INTERRUPT || rc == ERROR_SEM_OWNER_DIED) {
338 return WAIT_ABANDONED_W;
339 }
340 else
341 if(rc == ERROR_TIMEOUT) {
342 return WAIT_TIMEOUT_W;
343 }
344 return WAIT_OBJECT_0_W;
345}
346#endif
347
348#ifdef USE_OS2SEMAPHORES
349/*****************************************************************************
350 * Name : DWORD HMDeviceEventClass::WaitForSingleObjectEx
351 * Purpose : object synchronization
352 * Parameters: PHMHANDLEDATA pHMHandleData
353 * DWORD dwTimeout
354 * BOOL fAlertable
355 * Variables :
356 * Result : API returncode
357 * Remark :
358 * Status :
359 *
360 * Author : SvL
361 *****************************************************************************/
362
363DWORD HMDeviceEventClass::WaitForSingleObjectEx(PHMHANDLEDATA pHMHandleData,
364 DWORD dwTimeout,
365 BOOL fAlertable)
366{
367 dprintf2(("KERNEL32: HMDeviceEventClass::WaitForSingleObjectEx(%08xh,%08h,%08xh) not implemented correctly.\n",
368 pHMHandleData->hHMHandle, dwTimeout, fAlertable));
369
370 if(!(pHMHandleData->dwAccess & SYNCHRONIZE_W) )
371 {
372 dprintf(("ERROR: Access denied!!"));
373 SetLastError(ERROR_ACCESS_DENIED_W);
374 return WAIT_FAILED_W;
375 }
376
377 return WaitForSingleObject(pHMHandleData, dwTimeout);
378}
379#endif
380
381#ifdef USE_OS2SEMAPHORES
382/*****************************************************************************
383 * Name : BOOL HMDeviceEventClass::MsgWaitForMultipleObjects
384 * Purpose :
385 * Variables :
386 * Result :
387 * Remark :
388 * Status :
389 *
390 * Author : SvL
391 *****************************************************************************/
392DWORD HMDeviceEventClass::MsgWaitForMultipleObjects(PHMHANDLEDATA pHMHandleData,
393 DWORD nCount,
394 PHANDLE pHandles,
395 BOOL fWaitAll,
396 DWORD dwMilliseconds,
397 DWORD dwWakeMask)
398{
399 return HMSemMsgWaitForMultipleObjects(nCount, pHandles, fWaitAll, dwMilliseconds, dwWakeMask);
400}
401#endif
402
403#ifdef USE_OS2SEMAPHORES
404/*****************************************************************************
405 * Name : BOOL HMDeviceHandler::WaitForMultipleObjects
406 * Purpose :
407 * Variables :
408 * Result :
409 * Remark :
410 * Status :
411 *
412 * Author : SvL
413 *****************************************************************************/
414DWORD HMDeviceEventClass::WaitForMultipleObjects(PHMHANDLEDATA pHMHandleData,
415 DWORD cObjects,
416 PHANDLE lphObjects,
417 BOOL fWaitAll,
418 DWORD dwTimeout)
419{
420 return HMSemWaitForMultipleObjects(cObjects, lphObjects, fWaitAll, dwTimeout);
421}
422#endif
423
424/*****************************************************************************
425 * Name : HMSetEvent
426 * Purpose : router function for SetEvent
427 * Parameters:
428 * Variables :
429 * Result :
430 * Remark :
431 * Status :
432 *
433 * Author : Patrick Haller [Tue, 1999/07/06 20:44]
434 *****************************************************************************/
435
436BOOL HMDeviceEventClass::SetEvent(PHMHANDLEDATA pHMHandleData)
437{
438#ifdef USE_OS2SEMAPHORES
439 APIRET rc;
440
441 dprintf(("KERNEL32: HandleManager::Event::SetEvent(%08xh)\n",
442 pHMHandleData->hHMHandle));
443
444 if(!(pHMHandleData->dwAccess & EVENT_MODIFY_STATE_W) )
445 {
446 dprintf(("ERROR: Access denied!!"));
447 SetLastError(ERROR_ACCESS_DENIED_W);
448 return FALSE;
449 }
450
451 rc = DosPostEventSem(pHMHandleData->hHMHandle);
452 if(rc && rc != ERROR_ALREADY_POSTED) {
453 dprintf(("DosPostEventSem %x failed with rc %d", pHMHandleData->hHMHandle, rc));
454 SetLastError(error2WinError(rc));
455 return FALSE;
456 }
457 SetLastError(ERROR_SUCCESS_W);
458 return TRUE;
459#else
460 dprintf(("KERNEL32: HandleManager::Event::SetEvent(%08xh)\n",
461 pHMHandleData->hHMHandle));
462
463 return (O32_SetEvent(pHMHandleData->hHMHandle));
464#endif
465}
466
467
468/*****************************************************************************
469 * Name : HMPulseEvent
470 * Purpose : router function for PulseEvent
471 * Parameters:
472 * Variables :
473 * Result :
474 * Remark :
475 * Status :
476 *
477 * Author : Patrick Haller [Tue, 1999/07/06 20:44]
478 *****************************************************************************/
479
480BOOL HMDeviceEventClass::PulseEvent(PHMHANDLEDATA pHMHandleData)
481{
482#ifdef USE_OS2SEMAPHORES
483 APIRET rc;
484 ULONG count;
485
486 dprintf2(("KERNEL32: HandleManager::Event::PulseEvent(%08xh)\n",
487 pHMHandleData->hHMHandle));
488
489 if(!(pHMHandleData->dwAccess & EVENT_MODIFY_STATE_W) )
490 {
491 dprintf(("ERROR: Access denied!!"));
492 SetLastError(ERROR_ACCESS_DENIED_W);
493 return FALSE;
494 }
495
496 rc = DosPostEventSem(pHMHandleData->hHMHandle);
497 if(rc && rc != ERROR_ALREADY_POSTED) {
498 dprintf(("DosPostEventSem %x failed with rc %d", pHMHandleData->hHMHandle, rc));
499 SetLastError(error2WinError(rc));
500 return FALSE;
501 }
502 if(pHMHandleData->dwFlags == TRUE) {//fManualReset
503 rc = DosResetEventSem(pHMHandleData->hHMHandle, &count);
504 if(rc && rc != ERROR_ALREADY_RESET) {
505 dprintf(("DosResetEventSem %x failed with rc %d", pHMHandleData->hHMHandle, rc));
506 SetLastError(error2WinError(rc));
507 return FALSE;
508 }
509 }
510 SetLastError(ERROR_SUCCESS_W);
511 return TRUE;
512#else
513 dprintf2(("KERNEL32: HandleManager::Event::PulseEvent(%08xh)\n",
514 pHMHandleData->hHMHandle));
515
516 return (O32_PulseEvent(pHMHandleData->hHMHandle));
517#endif
518}
519
520
521/*****************************************************************************
522 * Name : HMResetEvent
523 * Purpose : router function for ResetEvent
524 * Parameters:
525 * Variables :
526 * Result :
527 * Remark :
528 * Status :
529 *
530 * Author : Patrick Haller [Tue, 1999/07/06 20:44]
531 *****************************************************************************/
532
533BOOL HMDeviceEventClass::ResetEvent(PHMHANDLEDATA pHMHandleData)
534{
535#ifdef USE_OS2SEMAPHORES
536 APIRET rc;
537 ULONG count;
538
539 dprintf2(("KERNEL32: HandleManager::Event::ResetEvent(%08xh)\n",
540 pHMHandleData->hHMHandle));
541
542 if(!(pHMHandleData->dwAccess & EVENT_MODIFY_STATE_W) )
543 {
544 dprintf(("ERROR: Access denied!!"));
545 SetLastError(ERROR_ACCESS_DENIED_W);
546 return FALSE;
547 }
548
549 rc = DosResetEventSem(pHMHandleData->hHMHandle, &count);
550 if(rc && rc != ERROR_ALREADY_RESET) {
551 dprintf(("DosResetEventSem %x failed with rc %d", pHMHandleData->hHMHandle, rc));
552 SetLastError(error2WinError(rc));
553 return FALSE;
554 }
555 SetLastError(ERROR_SUCCESS_W);
556 return TRUE;
557#else
558 dprintf2(("KERNEL32: HandleManager::Event::ResetEvent(%08xh)\n",
559 pHMHandleData->hHMHandle));
560
561 return (O32_ResetEvent(pHMHandleData->hHMHandle));
562#endif
563}
564
Note: See TracBrowser for help on using the repository browser.