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

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

semaphore update

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