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

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

semaphore updates

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