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

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

compile fixes

File size: 16.9 KB
Line 
1/* $Id: hmsemaphore.cpp,v 1.7 2001-06-23 07:45:43 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#include <os2wrap.h>
37#include <win32type.h>
38#include <win32api.h>
39#include <winconst.h>
40#else
41#include <os2win.h>
42#endif
43#include <stdlib.h>
44#include <string.h>
45#include <heapshared.h>
46#include "unicode.h"
47#include "misc.h"
48
49#include "HandleManager.H"
50#include "HMSemaphore.h"
51#include "oslibdos.h"
52
53#define DBG_LOCALLOG DBG_hmsemaphore
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
63#endif
64
65#ifdef USE_OS2SEMAPHORES
66typedef struct {
67 LONG currentCount;
68 LONG maximumCount;
69 LONG refCount;
70 HEV hev;
71} SEM_INFO, *PSEM_INFO;
72#endif
73
74/*****************************************************************************
75 * Defines *
76 *****************************************************************************/
77
78/*****************************************************************************
79 * Structures *
80 *****************************************************************************/
81
82/*****************************************************************************
83 * Local Prototypes *
84 *****************************************************************************/
85
86
87/*****************************************************************************
88 * Name : HMCreateSemaphore
89 * Purpose : router function for CreateSemaphore
90 * Parameters:
91 * Variables :
92 * Result :
93 * Remark :
94 * Status :
95 *
96 * Author : Patrick Haller [Tue, 1999/07/06 20:44]
97 *****************************************************************************/
98
99DWORD HMDeviceSemaphoreClass::CreateSemaphore(PHMHANDLEDATA pHMHandleData,
100 LPSECURITY_ATTRIBUTES lpsa,
101 LONG lInitialCount,
102 LONG lMaximumCount,
103 LPCTSTR lpszSemaphoreName)
104{
105#ifdef USE_OS2SEMAPHORES
106 APIRET rc;
107 HEV hev;
108 char szSemName[CCHMAXPATH];
109
110
111 dprintf(("KERNEL32: HandleManager::Semaphore::CreateSemaphore(%08xh,%08xh,%08xh,%08xh,%s)\n",
112 pHMHandleData,
113 lpsa,
114 lInitialCount,
115 lMaximumCount,
116 lpszSemaphoreName));
117
118 if(lMaximumCount <= 0 || lInitialCount < 0 || lInitialCount > lMaximumCount) {
119 dprintf(("ERROR: invalid parameter"));
120 return ERROR_INVALID_PARAMETER_W;
121 }
122
123 if(lpszSemaphoreName) {
124 strcpy(szSemName, "\\SEM32\\");
125 strcat(szSemName, lpszSemaphoreName);
126 lpszSemaphoreName = szSemName;
127 }
128 rc = DosCreateEventSem(lpszSemaphoreName, &hev, DCE_POSTONE, lInitialCount);
129
130 if(rc) {
131 dprintf(("DosCreateEventSem %x failed with rc %d", pHMHandleData->hHMHandle, rc));
132 pHMHandleData->hHMHandle = 0;
133 return error2WinError(rc);
134 }
135 pHMHandleData->dwAccess = SEMAPHORE_ALL_ACCESS_W;
136 PSEM_INFO pSemInfo = (PSEM_INFO)_smalloc(sizeof(SEM_INFO));
137 pSemInfo->refCount = 1;
138 pSemInfo->hev = hev;
139 pSemInfo->maximumCount = lMaximumCount;
140 pSemInfo->currentCount = lInitialCount;
141 pHMHandleData->hHMHandle = (DWORD)pSemInfo;
142 pHMHandleData->dwInternalType = HMTYPE_SEMAPHORE;
143 return ERROR_SUCCESS_W;
144#else
145 HANDLE hOpen32;
146
147 dprintf(("KERNEL32: HandleManager::Semaphore::CreateSemaphore(%08xh,%08xh,%08xh,%08xh,%s)\n",
148 pHMHandleData,
149 lpsa,
150 lInitialCount,
151 lMaximumCount,
152 lpszSemaphoreName));
153
154 hOpen32 = O32_CreateSemaphore(lpsa, // call Open32
155 lInitialCount,
156 lMaximumCount,
157 (LPTSTR)lpszSemaphoreName);
158
159 if (0 != hOpen32) // check success
160 {
161 pHMHandleData->hHMHandle = hOpen32; // save handle
162 return (NO_ERROR);
163 }
164 else
165 return (O32_GetLastError());
166#endif
167}
168
169
170/*****************************************************************************
171 * Name : HMOpenSemaphore
172 * Purpose : router function for OpenSemaphore
173 * Parameters:
174 * Variables :
175 * Result :
176 * Remark :
177 * Status :
178 *
179 * Author : Patrick Haller [Tue, 1999/07/06 20:44]
180 *****************************************************************************/
181
182DWORD HMDeviceSemaphoreClass::OpenSemaphore(PHMHANDLEDATA pHMHandleData,
183 BOOL fInheritHandle,
184 LPCTSTR lpszSemaphoreName)
185{
186#ifdef USE_OS2SEMAPHORES
187 HEV hev;
188 APIRET rc;
189 char szSemName[CCHMAXPATH];
190
191 //TODO: NOT WORKING (initialcount/maximumcount)
192 dprintf(("KERNEL32: HandleManager::Semaphore::OpenSemaphore(%08xh,%08xh,%s)\n",
193 pHMHandleData,
194 fInheritHandle,
195 lpszSemaphoreName));
196
197 if(lpszSemaphoreName == NULL) {
198 pHMHandleData->hHMHandle = 0;
199 return ERROR_INVALID_PARAMETER_W;
200 }
201
202 strcpy(szSemName, "\\SEM32\\");
203 strcat(szSemName, lpszSemaphoreName);
204 rc = DosOpenEventSem(szSemName, &hev);
205 if(rc) {
206 dprintf(("DosOpenEventSem %x failed with rc %d", pHMHandleData->hHMHandle, rc));
207 pHMHandleData->hHMHandle = 0;
208 return error2WinError(rc);
209 }
210 pHMHandleData->hHMHandle = hev;
211 pHMHandleData->dwInternalType = HMTYPE_SEMAPHORE;
212 return ERROR_SUCCESS_W;
213#else
214 HANDLE hOpen32;
215
216 dprintf(("KERNEL32: HandleManager::Semaphore::OpenSemaphore(%08xh,%08xh,%s)\n",
217 pHMHandleData,
218 fInheritHandle,
219 lpszSemaphoreName));
220
221 hOpen32 = O32_OpenSemaphore(pHMHandleData->dwAccess, // call Open32
222 fInheritHandle,
223 lpszSemaphoreName);
224
225 if (0 != hOpen32) // check success
226 {
227 pHMHandleData->hHMHandle = hOpen32; // save handle
228 return (NO_ERROR);
229 }
230 else
231 return (O32_GetLastError());
232#endif
233}
234
235/*****************************************************************************
236 * Name : HMDeviceEventClass::CloseHandle
237 * Purpose : close the handle
238 * Parameters: PHMHANDLEDATA pHMHandleData
239 * Variables :
240 * Result : API returncode
241 * Remark :
242 * Status :
243 *
244 * Author :
245 *****************************************************************************/
246
247#ifdef USE_OS2SEMAPHORES
248BOOL HMDeviceSemaphoreClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
249{
250 APIRET rc;
251 PSEM_INFO pSemInfo = (PSEM_INFO)pHMHandleData->hHMHandle;
252
253 if(pSemInfo) {
254 rc = DosCloseEventSem(pSemInfo->hev);
255 if(rc) {
256 dprintf(("DosCloseEventSem %x failed with rc %d", pSemInfo->hev, rc));
257 SetLastError(error2WinError(rc));
258 return FALSE;
259 }
260 if(InterlockedDecrement(&pSemInfo->refCount) == 0) {
261 free(pSemInfo);
262 }
263 }
264 return TRUE;
265}
266#endif
267
268
269/*****************************************************************************
270 * Name : HMDeviceEventClass::DuplicateHandle
271 * Purpose :
272 * Parameters:
273 * various parameters as required
274 * Variables :
275 * Result :
276 * Remark : the standard behaviour is to return an error code for non-
277 * existant request codes
278 * Status :
279 *
280 * Author :
281 *****************************************************************************/
282#ifdef USE_OS2SEMAPHORES
283BOOL HMDeviceSemaphoreClass::DuplicateHandle(PHMHANDLEDATA pHMHandleData, HANDLE srcprocess,
284 PHMHANDLEDATA pHMSrcHandle,
285 HANDLE destprocess,
286 PHANDLE desthandle,
287 DWORD fdwAccess,
288 BOOL fInherit,
289 DWORD fdwOptions,
290 DWORD fdwOdinOptions)
291{
292 APIRET rc;
293 HEV hev;
294 PSEM_INFO pSemInfo = (PSEM_INFO)pHMSrcHandle->hHMHandle;
295
296 dprintf(("KERNEL32:HandleManager::DuplicateHandle %s(%08x,%08x,%08x,%08x,%08x)",
297 lpHMDeviceName,
298 pHMHandleData,
299 srcprocess, pHMSrcHandle, destprocess, desthandle));
300
301 if(srcprocess != destprocess) {
302 DebugInt3();
303 SetLastError(ERROR_ACCESS_DENIED_W);
304 return FALSE;
305 }
306 InterlockedIncrement(&pSemInfo->refCount);
307 pHMHandleData->dwAccess = fdwAccess;
308 pHMHandleData->hHMHandle = (DWORD)pSemInfo;
309 pHMHandleData->dwInternalType = HMTYPE_SEMAPHORE;
310 SetLastError(ERROR_SUCCESS_W);
311 return TRUE;
312}
313#endif
314
315#ifdef USE_OS2SEMAPHORES
316/*****************************************************************************
317 * Name : DWORD HMDeviceSemaphoreClass::WaitForSingleObject
318 * Purpose : object synchronization
319 * Parameters: PHMHANDLEDATA pHMHandleData
320 * DWORD dwTimeout
321 * Variables :
322 * Result : API returncode
323 * Remark :
324 * Status :
325 *
326 * Author : SvL
327 *****************************************************************************/
328
329DWORD HMDeviceSemaphoreClass::WaitForSingleObject(PHMHANDLEDATA pHMHandleData,
330 DWORD dwTimeout)
331{
332 DWORD rc;
333
334 dprintf2(("KERNEL32: HMDeviceSemaphoreClass::WaitForSingleObject(%08xh %08xh)",
335 pHMHandleData->hHMHandle, dwTimeout));
336
337 if(!(pHMHandleData->dwAccess & SYNCHRONIZE_W) )
338 {
339 dprintf(("ERROR: Access denied!!"));
340 SetLastError(ERROR_ACCESS_DENIED_W);
341 return WAIT_FAILED_W;
342 }
343
344 PSEM_INFO pSemInfo = (PSEM_INFO)pHMHandleData->hHMHandle;
345
346 if(InterlockedDecrement(&pSemInfo->currentCount) >= 0) {
347 SetLastError(ERROR_SUCCESS_W);
348 return WAIT_OBJECT_0_W;
349 }
350
351 rc = DosWaitEventSem(pSemInfo->hev, dwTimeout);
352 if(rc && rc != ERROR_INTERRUPT && rc != ERROR_TIMEOUT && rc != ERROR_SEM_OWNER_DIED) {
353 dprintf(("DosWaitEventSem %x failed with rc %d", pSemInfo->hev, rc));
354 SetLastError(error2WinError(rc));
355 return WAIT_FAILED_W;
356 }
357 SetLastError(ERROR_SUCCESS_W);
358 if(rc == ERROR_INTERRUPT || rc == ERROR_SEM_OWNER_DIED) {
359 return WAIT_ABANDONED_W;
360 }
361 else
362 if(rc == ERROR_TIMEOUT) {
363 return WAIT_TIMEOUT_W;
364 }
365 return WAIT_OBJECT_0_W;
366}
367#endif
368
369#ifdef USE_OS2SEMAPHORES
370/*****************************************************************************
371 * Name : DWORD HMDeviceSemaphoreClass::WaitForSingleObjectEx
372 * Purpose : object synchronization
373 * Parameters: PHMHANDLEDATA pHMHandleData
374 * DWORD dwTimeout
375 * BOOL fAlertable
376 * Variables :
377 * Result : API returncode
378 * Remark :
379 * Status :
380 *
381 * Author : SvL
382 *****************************************************************************/
383
384DWORD HMDeviceSemaphoreClass::WaitForSingleObjectEx(PHMHANDLEDATA pHMHandleData,
385 DWORD dwTimeout,
386 BOOL fAlertable)
387{
388 dprintf2(("KERNEL32: HMDeviceSemaphoreClass::WaitForSingleObjectEx(%08xh,%08h,%08xh) not implemented correctly.\n",
389 pHMHandleData->hHMHandle, dwTimeout, fAlertable));
390
391 if(!(pHMHandleData->dwAccess & SYNCHRONIZE_W) )
392 {
393 dprintf(("ERROR: Access denied!!"));
394 SetLastError(ERROR_ACCESS_DENIED_W);
395 return WAIT_FAILED_W;
396 }
397
398 return WaitForSingleObject(pHMHandleData, dwTimeout);
399}
400#endif
401
402#ifdef USE_OS2SEMAPHORES
403/*****************************************************************************
404 * Name : BOOL HMDeviceSemaphoreClass::MsgWaitForMultipleObjects
405 * Purpose :
406 * Variables :
407 * Result :
408 * Remark :
409 * Status :
410 *
411 * Author : SvL
412 *****************************************************************************/
413DWORD HMDeviceSemaphoreClass::MsgWaitForMultipleObjects(PHMHANDLEDATA pHMHandleData,
414 DWORD nCount,
415 PHANDLE pHandles,
416 BOOL fWaitAll,
417 DWORD dwMilliseconds,
418 DWORD dwWakeMask)
419{
420 dprintf(("KERNEL32: ERROR: HandleManager::DeviceHandler::MsgWaitForMultipleObjects %08x %d %x %d %d %x",
421 pHMHandleData->hHMHandle, nCount, pHandles, fWaitAll, dwMilliseconds, dwWakeMask));
422
423 if(!(pHMHandleData->dwAccess & SYNCHRONIZE_W) )
424 {
425 dprintf(("ERROR: Access denied!!"));
426 SetLastError(ERROR_ACCESS_DENIED_W);
427 return WAIT_FAILED_W;
428 }
429
430 return WAIT_FAILED_W;
431}
432#endif
433
434#ifdef USE_OS2SEMAPHORES
435/*****************************************************************************
436 * Name : BOOL HMDeviceSemaphoreClass::WaitForMultipleObjects
437 * Purpose :
438 * Variables :
439 * Result :
440 * Remark :
441 * Status :
442 *
443 * Author : SvL
444 *****************************************************************************/
445DWORD HMDeviceSemaphoreClass::WaitForMultipleObjects(PHMHANDLEDATA pHMHandleData,
446 DWORD cObjects,
447 PHANDLE lphObjects,
448 BOOL fWaitAll,
449 DWORD dwTimeout)
450{
451 dprintf(("KERNEL32: ERROR: HandleManager::DeviceHandler::WaitForMultipleObjects %08x %d %x %d %x",
452 pHMHandleData->hHMHandle, cObjects, lphObjects, fWaitAll, dwTimeout));
453
454 if(!(pHMHandleData->dwAccess & SYNCHRONIZE_W) )
455 {
456 dprintf(("ERROR: Access denied!!"));
457 SetLastError(ERROR_ACCESS_DENIED_W);
458 return WAIT_FAILED_W;
459 }
460
461 return WAIT_FAILED_W;
462}
463#endif
464
465/*****************************************************************************
466 * Name : HMReleaseSemaphore
467 * Purpose : router function for ReleaseSemaphore
468 * Parameters:
469 * Variables :
470 * Result :
471 * Remark :
472 * Status :
473 *
474 * Author : Patrick Haller [Tue, 1999/07/06 20:44]
475 *****************************************************************************/
476
477BOOL HMDeviceSemaphoreClass::ReleaseSemaphore(PHMHANDLEDATA pHMHandleData,
478 LONG cReleaseCount,
479 LPLONG lpPreviousCount)
480{
481#ifdef USE_OS2SEMAPHORES
482 APIRET rc;
483 ULONG count;
484
485 dprintf2(("KERNEL32: HandleManager::Semaphore::ReleaseSemaphore(%08xh,%08xh,%08xh)\n",
486 pHMHandleData->hHMHandle,
487 cReleaseCount,
488 lpPreviousCount));
489
490 if(!(pHMHandleData->dwAccess & SEMAPHORE_MODIFY_STATE_W) )
491 {
492 dprintf(("ERROR: Access denied!!"));
493 SetLastError(ERROR_ACCESS_DENIED_W);
494 return FALSE;
495 }
496
497 PSEM_INFO pSemInfo = (PSEM_INFO)pHMHandleData->hHMHandle;
498
499 if(InterlockedIncrement(&pSemInfo->currentCount) > 0) {
500 //TODO: this is NOT thread safe:
501 if(pSemInfo->currentCount > pSemInfo->maximumCount) {
502 pSemInfo->currentCount = pSemInfo->maximumCount;
503 }
504 SetLastError(ERROR_SUCCESS_W);
505 return TRUE;
506 }
507
508 rc = DosResetEventSem(pSemInfo->hev, &count);
509 if(rc) {
510 dprintf(("DosResetEventSem %x failed with rc %d", pSemInfo->hev, rc));
511 SetLastError(error2WinError(rc));
512 return FALSE;
513 }
514 SetLastError(ERROR_SUCCESS_W);
515 return TRUE;
516#else
517 dprintf(("KERNEL32: HandleManager::Semaphore::ReleaseSemaphore(%08xh,%08xh,%08xh)\n",
518 pHMHandleData->hHMHandle,
519 cReleaseCount,
520 lpPreviousCount));
521
522 return (O32_ReleaseSemaphore(pHMHandleData->hHMHandle,
523 cReleaseCount,
524 lpPreviousCount));
525#endif
526}
527
Note: See TracBrowser for help on using the repository browser.