source: trunk/src/kernel32/hmsemaphore.cpp@ 6086

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

added cdrom get/setvolume ioctls

File size: 26.4 KB
Line 
1/* $Id: hmsemaphore.cpp,v 1.9 2001-06-23 19:43:50 sandervl Exp $ */
2
3/*
4 * Win32 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 CreateSemaphore is called for existing named event semaphore?
9 * (see HMCreateSemaphore in handlemanager.cpp)
10 * TODO: OpenSemaphore does not work. (get SEM_INFO pointer)
11 * TODO: Name collisions with files & mutex not allowed. Check if this can happen in OS/2
12 *
13 * Project Odin Software License can be found in LICENSE.TXT
14 *
15 * Copyright 2001 Sander van Leeuwen (sandervl@xs4all.nl)
16 */
17
18#undef DEBUG_LOCAL
19//#define DEBUG_LOCAL
20
21
22/*****************************************************************************
23 * Remark *
24 *****************************************************************************
25
26 */
27
28
29/*****************************************************************************
30 * Includes *
31 *****************************************************************************/
32
33#ifdef USE_OS2SEMAPHORES
34#define INCL_DOSSEMAPHORES
35#define INCL_DOSERRORS
36#define INCL_WIN
37#include <os2wrap.h>
38#include <win32type.h>
39#include <win32api.h>
40#include <winconst.h>
41#else
42#include <os2win.h>
43#endif
44#include <stdlib.h>
45#include <string.h>
46#include <heapshared.h>
47#include "unicode.h"
48#include "misc.h"
49
50#include "HandleManager.H"
51#include "HMSemaphore.h"
52#include "oslibdos.h"
53
54#define DBG_LOCALLOG DBG_hmsemaphore
55#include "dbglocal.h"
56
57#ifndef DCE_AUTORESET
58#define DCE_AUTORESET 0x1000 /* DosCreateEventSem option to auto-reset */
59 /* event semaphore on post. */
60#define DCE_POSTONE 0x0800 /* DosCreateEventSem option to post only */
61 /* waiter and auto-reset the semaphore when*/
62 /* there are multiple waiters. */
63
64#endif
65
66/*****************************************************************************
67 * Defines *
68 *****************************************************************************/
69
70/*****************************************************************************
71 * Structures *
72 *****************************************************************************/
73
74/*****************************************************************************
75 * Local Prototypes *
76 *****************************************************************************/
77
78
79/*****************************************************************************
80 * Name : HMCreateSemaphore
81 * Purpose : router function for CreateSemaphore
82 * Parameters:
83 * Variables :
84 * Result :
85 * Remark :
86 * Status :
87 *
88 * Author : Patrick Haller [Tue, 1999/07/06 20:44]
89 *****************************************************************************/
90
91DWORD HMDeviceSemaphoreClass::CreateSemaphore(PHMHANDLEDATA pHMHandleData,
92 LPSECURITY_ATTRIBUTES lpsa,
93 LONG lInitialCount,
94 LONG lMaximumCount,
95 LPCTSTR lpszSemaphoreName)
96{
97#ifdef USE_OS2SEMAPHORES
98 APIRET rc;
99 HEV hev;
100 char szSemName[CCHMAXPATH];
101
102
103 dprintf(("KERNEL32: HandleManager::Semaphore::CreateSemaphore(%08xh,%08xh,%08xh,%08xh,%s)\n",
104 pHMHandleData,
105 lpsa,
106 lInitialCount,
107 lMaximumCount,
108 lpszSemaphoreName));
109
110 if(lMaximumCount <= 0 || lInitialCount < 0 || lInitialCount > lMaximumCount) {
111 dprintf(("ERROR: invalid parameter"));
112 return ERROR_INVALID_PARAMETER_W;
113 }
114
115 if(lpszSemaphoreName) {
116 strcpy(szSemName, "\\SEM32\\");
117 strcat(szSemName, lpszSemaphoreName);
118 lpszSemaphoreName = szSemName;
119 FixSemName((char *)lpszSemaphoreName);
120 }
121 rc = DosCreateEventSem(lpszSemaphoreName, &hev, DCE_POSTONE, lInitialCount);
122
123 if(rc) {
124 dprintf(("DosCreateEventSem %x failed with rc %d", pHMHandleData->hHMHandle, rc));
125 pHMHandleData->hHMHandle = 0;
126 return error2WinError(rc);
127 }
128 pHMHandleData->dwAccess = SEMAPHORE_ALL_ACCESS_W;
129 PSEM_INFO pSemInfo = (PSEM_INFO)_smalloc(sizeof(SEM_INFO));
130 pSemInfo->refCount = 1;
131 pSemInfo->hev = hev;
132 pSemInfo->maximumCount = lMaximumCount;
133 pSemInfo->currentCount = lInitialCount;
134 pHMHandleData->hHMHandle = (DWORD)pSemInfo;
135 pHMHandleData->dwInternalType = HMTYPE_SEMAPHORE;
136 return ERROR_SUCCESS_W;
137#else
138 HANDLE hOpen32;
139
140 dprintf(("KERNEL32: HandleManager::Semaphore::CreateSemaphore(%08xh,%08xh,%08xh,%08xh,%s)\n",
141 pHMHandleData,
142 lpsa,
143 lInitialCount,
144 lMaximumCount,
145 lpszSemaphoreName));
146
147 hOpen32 = O32_CreateSemaphore(lpsa, // call Open32
148 lInitialCount,
149 lMaximumCount,
150 (LPTSTR)lpszSemaphoreName);
151
152 if (0 != hOpen32) // check success
153 {
154 pHMHandleData->hHMHandle = hOpen32; // save handle
155 return (NO_ERROR);
156 }
157 else
158 return (O32_GetLastError());
159#endif
160}
161
162
163/*****************************************************************************
164 * Name : HMOpenSemaphore
165 * Purpose : router function for OpenSemaphore
166 * Parameters:
167 * Variables :
168 * Result :
169 * Remark :
170 * Status :
171 *
172 * Author : Patrick Haller [Tue, 1999/07/06 20:44]
173 *****************************************************************************/
174
175DWORD HMDeviceSemaphoreClass::OpenSemaphore(PHMHANDLEDATA pHMHandleData,
176 BOOL fInheritHandle,
177 LPCTSTR lpszSemaphoreName)
178{
179#ifdef USE_OS2SEMAPHORES
180 HEV hev;
181 APIRET rc;
182 char szSemName[CCHMAXPATH];
183
184 //TODO: NOT WORKING (initialcount/maximumcount)
185 dprintf(("KERNEL32: HandleManager::Semaphore::OpenSemaphore(%08xh,%08xh,%s)\n",
186 pHMHandleData,
187 fInheritHandle,
188 lpszSemaphoreName));
189
190 if(lpszSemaphoreName == NULL) {
191 pHMHandleData->hHMHandle = 0;
192 return ERROR_INVALID_PARAMETER_W;
193 }
194
195 strcpy(szSemName, "\\SEM32\\");
196 strcat(szSemName, lpszSemaphoreName);
197 FixSemName(szSemName);
198 rc = DosOpenEventSem(szSemName, &hev);
199 if(rc) {
200 dprintf(("DosOpenEventSem %x failed with rc %d", pHMHandleData->hHMHandle, rc));
201 pHMHandleData->hHMHandle = 0;
202 return error2WinError(rc);
203 }
204 pHMHandleData->hHMHandle = hev;
205 pHMHandleData->dwInternalType = HMTYPE_SEMAPHORE;
206 return ERROR_SUCCESS_W;
207#else
208 HANDLE hOpen32;
209
210 dprintf(("KERNEL32: HandleManager::Semaphore::OpenSemaphore(%08xh,%08xh,%s)\n",
211 pHMHandleData,
212 fInheritHandle,
213 lpszSemaphoreName));
214
215 hOpen32 = O32_OpenSemaphore(pHMHandleData->dwAccess, // call Open32
216 fInheritHandle,
217 lpszSemaphoreName);
218
219 if (0 != hOpen32) // check success
220 {
221 pHMHandleData->hHMHandle = hOpen32; // save handle
222 return (NO_ERROR);
223 }
224 else
225 return (O32_GetLastError());
226#endif
227}
228
229/*****************************************************************************
230 * Name : HMDeviceEventClass::CloseHandle
231 * Purpose : close the handle
232 * Parameters: PHMHANDLEDATA pHMHandleData
233 * Variables :
234 * Result : API returncode
235 * Remark :
236 * Status :
237 *
238 * Author :
239 *****************************************************************************/
240
241#ifdef USE_OS2SEMAPHORES
242BOOL HMDeviceSemaphoreClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
243{
244 APIRET rc;
245 PSEM_INFO pSemInfo = (PSEM_INFO)pHMHandleData->hHMHandle;
246
247 if(pSemInfo) {
248 rc = DosCloseEventSem(pSemInfo->hev);
249 if(rc) {
250 dprintf(("DosCloseEventSem %x failed with rc %d", pSemInfo->hev, rc));
251 SetLastError(error2WinError(rc));
252 return FALSE;
253 }
254 if(InterlockedDecrement(&pSemInfo->refCount) == 0) {
255 free(pSemInfo);
256 }
257 }
258 return TRUE;
259}
260#endif
261
262
263/*****************************************************************************
264 * Name : HMDeviceEventClass::DuplicateHandle
265 * Purpose :
266 * Parameters:
267 * various parameters as required
268 * Variables :
269 * Result :
270 * Remark : the standard behaviour is to return an error code for non-
271 * existant request codes
272 * Status :
273 *
274 * Author :
275 *****************************************************************************/
276#ifdef USE_OS2SEMAPHORES
277BOOL HMDeviceSemaphoreClass::DuplicateHandle(PHMHANDLEDATA pHMHandleData, HANDLE srcprocess,
278 PHMHANDLEDATA pHMSrcHandle,
279 HANDLE destprocess,
280 PHANDLE desthandle,
281 DWORD fdwAccess,
282 BOOL fInherit,
283 DWORD fdwOptions,
284 DWORD fdwOdinOptions)
285{
286 APIRET rc;
287 HEV hev;
288 PSEM_INFO pSemInfo = (PSEM_INFO)pHMSrcHandle->hHMHandle;
289
290 dprintf(("KERNEL32:HandleManager::DuplicateHandle %s(%08x,%08x,%08x,%08x,%08x)",
291 lpHMDeviceName,
292 pHMHandleData,
293 srcprocess, pHMSrcHandle, destprocess, desthandle));
294
295 if(srcprocess != destprocess) {
296 DebugInt3();
297 SetLastError(ERROR_ACCESS_DENIED_W);
298 return FALSE;
299 }
300 InterlockedIncrement(&pSemInfo->refCount);
301 pHMHandleData->dwAccess = fdwAccess;
302 pHMHandleData->hHMHandle = (DWORD)pSemInfo;
303 pHMHandleData->dwInternalType = HMTYPE_SEMAPHORE;
304 SetLastError(ERROR_SUCCESS_W);
305 return TRUE;
306}
307#endif
308
309#ifdef USE_OS2SEMAPHORES
310/*****************************************************************************
311 * Name : DWORD HMDeviceSemaphoreClass::WaitForSingleObject
312 * Purpose : object synchronization
313 * Parameters: PHMHANDLEDATA pHMHandleData
314 * DWORD dwTimeout
315 * Variables :
316 * Result : API returncode
317 * Remark :
318 * Status :
319 *
320 * Author : SvL
321 *****************************************************************************/
322
323DWORD HMDeviceSemaphoreClass::WaitForSingleObject(PHMHANDLEDATA pHMHandleData,
324 DWORD dwTimeout)
325{
326 DWORD rc;
327
328 dprintf2(("KERNEL32: HMDeviceSemaphoreClass::WaitForSingleObject(%08xh %08xh)",
329 pHMHandleData->hHMHandle, dwTimeout));
330
331 if(!(pHMHandleData->dwAccess & SYNCHRONIZE_W) )
332 {
333 dprintf(("ERROR: Access denied!!"));
334 SetLastError(ERROR_ACCESS_DENIED_W);
335 return WAIT_FAILED_W;
336 }
337
338 PSEM_INFO pSemInfo = (PSEM_INFO)pHMHandleData->hHMHandle;
339
340 if(InterlockedDecrement(&pSemInfo->currentCount) >= 0) {
341 SetLastError(ERROR_SUCCESS_W);
342 return WAIT_OBJECT_0_W;
343 }
344
345 rc = DosWaitEventSem(pSemInfo->hev, dwTimeout);
346 if(rc && rc != ERROR_INTERRUPT && rc != ERROR_TIMEOUT && rc != ERROR_SEM_OWNER_DIED) {
347 dprintf(("DosWaitEventSem %x failed with rc %d", pSemInfo->hev, rc));
348 SetLastError(error2WinError(rc));
349 return WAIT_FAILED_W;
350 }
351 SetLastError(ERROR_SUCCESS_W);
352 if(rc == ERROR_INTERRUPT || rc == ERROR_SEM_OWNER_DIED) {
353 return WAIT_ABANDONED_W;
354 }
355 else
356 if(rc == ERROR_TIMEOUT) {
357 return WAIT_TIMEOUT_W;
358 }
359 return WAIT_OBJECT_0_W;
360}
361#endif
362
363#ifdef USE_OS2SEMAPHORES
364/*****************************************************************************
365 * Name : DWORD HMDeviceSemaphoreClass::WaitForSingleObjectEx
366 * Purpose : object synchronization
367 * Parameters: PHMHANDLEDATA pHMHandleData
368 * DWORD dwTimeout
369 * BOOL fAlertable
370 * Variables :
371 * Result : API returncode
372 * Remark :
373 * Status :
374 *
375 * Author : SvL
376 *****************************************************************************/
377
378DWORD HMDeviceSemaphoreClass::WaitForSingleObjectEx(PHMHANDLEDATA pHMHandleData,
379 DWORD dwTimeout,
380 BOOL fAlertable)
381{
382 dprintf2(("KERNEL32: HMDeviceSemaphoreClass::WaitForSingleObjectEx(%08xh,%08h,%08xh) not implemented correctly.\n",
383 pHMHandleData->hHMHandle, dwTimeout, fAlertable));
384
385 if(!(pHMHandleData->dwAccess & SYNCHRONIZE_W) )
386 {
387 dprintf(("ERROR: Access denied!!"));
388 SetLastError(ERROR_ACCESS_DENIED_W);
389 return WAIT_FAILED_W;
390 }
391
392 return WaitForSingleObject(pHMHandleData, dwTimeout);
393}
394#endif
395
396#ifdef USE_OS2SEMAPHORES
397/*****************************************************************************
398 * Name : BOOL HMDeviceSemaphoreClass::MsgWaitForMultipleObjects
399 * Purpose :
400 * Variables :
401 * Result :
402 * Remark :
403 * Status :
404 *
405 * Author : SvL
406 *****************************************************************************/
407DWORD HMDeviceSemaphoreClass::MsgWaitForMultipleObjects(PHMHANDLEDATA pHMHandleData,
408 DWORD nCount,
409 PHANDLE pHandles,
410 BOOL fWaitAll,
411 DWORD dwMilliseconds,
412 DWORD dwWakeMask)
413{
414 return HMSemMsgWaitForMultipleObjects(nCount, pHandles, fWaitAll, dwMilliseconds, dwWakeMask);
415}
416
417DWORD HMSemMsgWaitForMultipleObjects(DWORD cObjects,
418 PHANDLE lphObjects,
419 BOOL fWaitAll,
420 DWORD dwTimeout,
421 DWORD dwWakeMask)
422{
423 PHMHANDLEDATA *pHandles;
424 HMUX hmux;
425 PSEMRECORD pSemRec;
426 int i, j;
427 APIRET rc;
428 ULONG ulUser;
429 static HMODULE hUser32 = 0;
430 static BOOL (* WINAPI pfnPeekMessageA)(LPMSG,HWND,UINT,UINT,UINT);
431
432 dprintf(("KERNEL32: WaitForMultipleObjects %d %x %d %x",
433 cObjects, lphObjects, fWaitAll, dwTimeout));
434
435 if(pfnPeekMessageA == NULL) {
436 hUser32 = LoadLibraryA("USER32.DLL");
437 *(FARPROC *)&pfnPeekMessageA = GetProcAddress(hUser32,"PeekMessageA");
438 }
439
440 if(cObjects == 1) {
441 //Can't use DosCreateMuxWaitSem here (will return error 292)
442 PHMHANDLEDATA pHandle = HMQueryHandleData(lphObjects[0]);
443 if(pHandle == NULL) {
444 return WAIT_FAILED_W;
445 }
446 if(!(pHandle->dwAccess & SYNCHRONIZE_W) )
447 {
448 dprintf(("ERROR: Access denied (handle %x, index 0)!!", lphObjects[0]));
449 SetLastError(ERROR_ACCESS_DENIED_W);
450 return WAIT_FAILED_W;
451 }
452
453 switch(pHandle->dwInternalType) {
454 case HMTYPE_SEMAPHORE:
455 {
456 PSEM_INFO pSemInfo = (PSEM_INFO)pHandle->hHMHandle;
457
458 dprintf(("KERNEL32: HMWaitForMultipleObjects(S): handle 0: ODIN-%08xh, OS/2-%08xh",
459 lphObjects[0], pSemInfo->hev));
460 if(InterlockedDecrement(&pSemInfo->currentCount) >= 0) {
461 return WAIT_OBJECT_0_W;
462 }
463 rc = WinWaitEventSem(pSemInfo->hev, dwTimeout);
464 break;
465 }
466 case HMTYPE_EVENTSEM:
467 dprintf(("KERNEL32: HMWaitForMultipleObjects(E): handle 0: ODIN-%08xh, OS/2-%08xh",
468 lphObjects[0], pHandle->hHMHandle));
469 rc = WinWaitEventSem((HEV)pHandle->hHMHandle, dwTimeout);
470 break;
471 case HMTYPE_MUTEXSEM:
472 dprintf(("KERNEL32: HMWaitForMultipleObjects(M): handle 0: ODIN-%08xh, OS/2-%08xh",
473 lphObjects[0], pHandle->hHMHandle));
474 rc = WinRequestMutexSem((HMTX)pHandle->hHMHandle, dwTimeout);
475 break;
476 }
477 if(rc && rc != ERROR_INTERRUPT && rc != ERROR_TIMEOUT && rc != ERROR_SEM_OWNER_DIED) {
478 dprintf(("WinWaitEventSem/WinRequestMutexSem %x failed with rc %d", pHandle->hHMHandle, rc));
479 SetLastError(error2WinError(rc));
480 return WAIT_FAILED_W;
481 }
482 SetLastError(ERROR_SUCCESS_W);
483 if(rc == ERROR_INTERRUPT || rc == ERROR_SEM_OWNER_DIED) {
484 dprintf(("WAIT_ABANDONED_W (rc %d)", rc));
485 return WAIT_ABANDONED_W;
486 }
487 else
488 if(rc == ERROR_TIMEOUT) {
489 dprintf(("WAIT_TIMEOUT_W (rc %d)", rc));
490 return WAIT_TIMEOUT_W;
491 }
492 MSG msg ;
493
494 if(pfnPeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE_W) == TRUE) {
495 dprintf(("WAIT_OBJECT_0_W+1 (rc %d)", rc));
496 return WAIT_OBJECT_0_W + 1;
497 }
498 dprintf(("WAIT_OBJECT_0_W+1 (rc %d)", rc));
499 return WAIT_OBJECT_0_W;
500 }
501 pHandles = (PHMHANDLEDATA *)alloca(cObjects * sizeof(PHMHANDLEDATA));
502 pSemRec = (PSEMRECORD)alloca(cObjects * sizeof(SEMRECORD));
503 if(pHandles == NULL || pSemRec == NULL) {
504 dprintf(("ERROR: out of memory!!"));
505 SetLastError(ERROR_OUTOFMEMORY_W);
506 return WAIT_FAILED_W;
507 }
508 for(i=0;i<cObjects;i++) {
509 pHandles[i] = HMQueryHandleData(lphObjects[i]);
510 if(pHandles[i] == NULL) {
511 dprintf(("ERROR: handle %x not recognized", lphObjects[i]));
512 SetLastError(ERROR_INVALID_HANDLE_W);
513 return WAIT_FAILED_W;
514 }
515 if(!(pHandles[i]->dwAccess & SYNCHRONIZE_W) )
516 {
517 dprintf(("ERROR: Access denied (handle %x, index %d)!!", lphObjects[i], i));
518 SetLastError(ERROR_ACCESS_DENIED_W);
519 return WAIT_FAILED_W;
520 }
521 if(pHandles[i]->dwInternalType == HMTYPE_SEMAPHORE) {
522 PSEM_INFO pSemInfo = (PSEM_INFO)pHandles[i]->hHMHandle;
523 dprintf(("KERNEL32: HMWaitForMultipleObjects: handle %3i: ODIN-%08xh, OS/2-%08xh",
524 i, lphObjects[i], pSemInfo->hev));
525 }
526 else
527 dprintf(("KERNEL32: HMWaitForMultipleObjects: handle %3i: ODIN-%08xh, OS/2-%08xh",
528 i, lphObjects[i], pHandles[i]->hHMHandle));
529
530 }
531 j = 0;
532 for(i=0;i<cObjects;i++) {
533 if(pHandles[i]->dwInternalType == HMTYPE_SEMAPHORE) {
534 PSEM_INFO pSemInfo = (PSEM_INFO)pHandles[i]->hHMHandle;
535
536 if(InterlockedDecrement(&pSemInfo->currentCount) >= 0) {
537 if(!fWaitAll) {
538 return WAIT_OBJECT_0_W + i;
539 }
540 }
541 else {
542 pSemRec[j].hsemCur = (HSEM)pSemInfo->hev;
543 pSemRec[j].ulUser = j;
544 j++;
545 }
546 }
547 else {
548 pSemRec[j].hsemCur = (HSEM)pHandles[i]->hHMHandle;
549 pSemRec[j].ulUser = j;
550 j++;
551 }
552 }
553 rc = DosCreateMuxWaitSem(NULL, &hmux, j, pSemRec, (fWaitAll) ? DCMW_WAIT_ALL : DCMW_WAIT_ANY);
554 if(rc) {
555 dprintf(("DosCreateMuxWaitSem failed with rc %d", rc));
556 SetLastError(error2WinError(rc));
557 return WAIT_FAILED_W;
558 }
559 ulUser = -1;
560 rc = WinWaitMuxWaitSem(hmux, dwTimeout, &ulUser);
561 DosCloseMuxWaitSem(hmux);
562 if(rc && rc != ERROR_INTERRUPT && rc != ERROR_TIMEOUT && rc != ERROR_SEM_OWNER_DIED) {
563 dprintf(("DosWaitMuxWaitSem %x failed with rc %d", hmux, rc));
564 SetLastError(error2WinError(rc));
565 return WAIT_FAILED_W;
566 }
567 SetLastError(ERROR_SUCCESS_W);
568 if(rc == ERROR_INTERRUPT || rc == ERROR_SEM_OWNER_DIED) {
569 //TODO: add index of handle that caused the error....
570 dprintf(("WAIT_ABANDONED_W"));
571 return WAIT_ABANDONED_W;
572 }
573 else
574 if(rc == ERROR_TIMEOUT) {
575 dprintf(("WAIT_TIMEOUT_W"));
576 return WAIT_TIMEOUT_W;
577 }
578 if(ulUser == -1) {
579 dprintf(("WAIT_OBJECT_0_W+%d", cObjects));
580 return WAIT_OBJECT_0_W + cObjects; //message waiting
581 }
582 dprintf(("WAIT_OBJECT_0_W+%d", ulUser));
583 return WAIT_OBJECT_0_W + ulUser;
584}
585
586#endif
587
588#ifdef USE_OS2SEMAPHORES
589/*****************************************************************************
590 * Name : BOOL HMDeviceSemaphoreClass::WaitForMultipleObjects
591 * Purpose :
592 * Variables :
593 * Result :
594 * Remark :
595 * Status :
596 *
597 * Author : SvL
598 *****************************************************************************/
599DWORD HMDeviceSemaphoreClass::WaitForMultipleObjects(PHMHANDLEDATA pHMHandleData,
600 DWORD cObjects,
601 PHANDLE lphObjects,
602 BOOL fWaitAll,
603 DWORD dwTimeout)
604{
605 return HMSemWaitForMultipleObjects(cObjects, lphObjects, fWaitAll, dwTimeout);
606}
607
608DWORD HMSemWaitForMultipleObjects(DWORD cObjects,
609 PHANDLE lphObjects,
610 BOOL fWaitAll,
611 DWORD dwTimeout)
612{
613 PHMHANDLEDATA *pHandles;
614 HMUX hmux;
615 PSEMRECORD pSemRec;
616 int i, j;
617 APIRET rc;
618 ULONG ulUser;
619
620 dprintf(("KERNEL32: WaitForMultipleObjects %d %x %d %x",
621 cObjects, lphObjects, fWaitAll, dwTimeout));
622
623 pHandles = (PHMHANDLEDATA *)alloca(cObjects * sizeof(PHMHANDLEDATA));
624 pSemRec = (PSEMRECORD)alloca(cObjects * sizeof(SEMRECORD));
625 if(pHandles == NULL || pSemRec == NULL) {
626 dprintf(("ERROR: out of memory!!"));
627 SetLastError(ERROR_OUTOFMEMORY_W);
628 return WAIT_FAILED_W;
629 }
630 for(i=0;i<cObjects;i++) {
631 pHandles[i] = HMQueryHandleData(lphObjects[i]);
632 if(pHandles[i] == NULL) {
633 dprintf(("ERROR: handle %x not recognized", lphObjects[i]));
634 }
635 if(!(pHandles[i]->dwAccess & EVENT_MODIFY_STATE_W) )
636 {
637 dprintf(("ERROR: Access denied (handle %x, index %d)!!", lphObjects[i], i));
638 SetLastError(ERROR_INVALID_HANDLE_W);
639 return WAIT_FAILED_W;
640 }
641 if(pHandles[i]->dwInternalType == HMTYPE_SEMAPHORE) {
642 PSEM_INFO pSemInfo = (PSEM_INFO)pHandles[i]->hHMHandle;
643 dprintf(("KERNEL32: HMWaitForMultipleObjects: handle %3i: ODIN-%08xh, OS/2-%08xh",
644 i, lphObjects[i], pSemInfo->hev));
645 }
646 else
647 dprintf(("KERNEL32: HMWaitForMultipleObjects: handle %3i: ODIN-%08xh, OS/2-%08xh",
648 i, lphObjects[i], pHandles[i]->hHMHandle));
649
650 }
651 j = 0;
652 for(i=0;i<cObjects;i++) {
653 if(pHandles[i]->dwInternalType == HMTYPE_SEMAPHORE) {
654 PSEM_INFO pSemInfo = (PSEM_INFO)pHandles[i]->hHMHandle;
655
656 if(InterlockedDecrement(&pSemInfo->currentCount) >= 0) {
657 if(!fWaitAll) {
658 return WAIT_OBJECT_0_W + i;
659 }
660 }
661 else {
662 pSemRec[j].hsemCur = (HSEM)pSemInfo->hev;
663 pSemRec[j].ulUser = j;
664 j++;
665 }
666 }
667 else {
668 pSemRec[j].hsemCur = (HSEM)pHandles[i]->hHMHandle;
669 pSemRec[j].ulUser = j;
670 j++;
671 }
672 }
673 rc = DosCreateMuxWaitSem(NULL, &hmux, j, pSemRec, (fWaitAll) ? DCMW_WAIT_ALL : DCMW_WAIT_ANY);
674 if(rc) {
675 dprintf(("DosCreateMuxWaitSem failed with rc %d", rc));
676 SetLastError(error2WinError(rc));
677 return WAIT_FAILED_W;
678 }
679 rc = DosWaitMuxWaitSem(hmux, dwTimeout, &ulUser);
680 DosCloseMuxWaitSem(hmux);
681 if(rc && rc != ERROR_INTERRUPT && rc != ERROR_TIMEOUT && rc != ERROR_SEM_OWNER_DIED) {
682 dprintf(("DosWaitMuxWaitSem %x failed with rc %d", hmux, rc));
683 SetLastError(error2WinError(rc));
684 return WAIT_FAILED_W;
685 }
686 SetLastError(ERROR_SUCCESS_W);
687 if(rc == ERROR_INTERRUPT || rc == ERROR_SEM_OWNER_DIED) {
688 //TODO: add index of handle that caused the error....
689 return WAIT_ABANDONED_W;
690 }
691 else
692 if(rc == ERROR_TIMEOUT) {
693 return WAIT_TIMEOUT_W;
694 }
695 return WAIT_OBJECT_0_W + ulUser;
696}
697
698#endif
699
700/*****************************************************************************
701 * Name : HMReleaseSemaphore
702 * Purpose : router function for ReleaseSemaphore
703 * Parameters:
704 * Variables :
705 * Result :
706 * Remark :
707 * Status :
708 *
709 * Author : Patrick Haller [Tue, 1999/07/06 20:44]
710 *****************************************************************************/
711
712BOOL HMDeviceSemaphoreClass::ReleaseSemaphore(PHMHANDLEDATA pHMHandleData,
713 LONG cReleaseCount,
714 LPLONG lpPreviousCount)
715{
716#ifdef USE_OS2SEMAPHORES
717 APIRET rc;
718 ULONG count;
719
720 dprintf2(("KERNEL32: HandleManager::Semaphore::ReleaseSemaphore(%08xh,%08xh,%08xh)\n",
721 pHMHandleData->hHMHandle,
722 cReleaseCount,
723 lpPreviousCount));
724
725 if(!(pHMHandleData->dwAccess & SEMAPHORE_MODIFY_STATE_W) )
726 {
727 dprintf(("ERROR: Access denied!!"));
728 SetLastError(ERROR_ACCESS_DENIED_W);
729 return FALSE;
730 }
731
732 PSEM_INFO pSemInfo = (PSEM_INFO)pHMHandleData->hHMHandle;
733
734 if(InterlockedIncrement(&pSemInfo->currentCount) > 0) {
735 //TODO: this is NOT thread safe:
736 if(pSemInfo->currentCount > pSemInfo->maximumCount) {
737 pSemInfo->currentCount = pSemInfo->maximumCount;
738 }
739 SetLastError(ERROR_SUCCESS_W);
740 return TRUE;
741 }
742
743 rc = DosResetEventSem(pSemInfo->hev, &count);
744 if(rc && rc != ERROR_ALREADY_RESET) {
745 dprintf(("DosResetEventSem %x failed with rc %d", pSemInfo->hev, rc));
746 SetLastError(error2WinError(rc));
747 return FALSE;
748 }
749 SetLastError(ERROR_SUCCESS_W);
750 return TRUE;
751#else
752 dprintf(("KERNEL32: HandleManager::Semaphore::ReleaseSemaphore(%08xh,%08xh,%08xh)\n",
753 pHMHandleData->hHMHandle,
754 cReleaseCount,
755 lpPreviousCount));
756
757 return (O32_ReleaseSemaphore(pHMHandleData->hHMHandle,
758 cReleaseCount,
759 lpPreviousCount));
760#endif
761}
762
763//******************************************************************************
764//Replaces illegal characters in semaphore name (or else OS/2 will return
765//ERROR_INVALID_NAME
766//******************************************************************************
767void FixSemName(char *lpszSemaphoreName)
768{
769 while(TRUE) {
770 switch(*lpszSemaphoreName) {
771 case 0:
772 return;
773 case '?':
774 case ':':
775 *lpszSemaphoreName = '_';
776 break;
777 }
778 lpszSemaphoreName++;
779 }
780}
781//******************************************************************************
782//******************************************************************************
Note: See TracBrowser for help on using the repository browser.