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

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

semaphore updates

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