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

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

semaphore rewrite (not activated)

File size: 11.3 KB
Line 
1/* $Id: hmsemaphore.cpp,v 1.4 2001-06-19 10:50:25 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: Name collisions with files & mutex not allowed. Check if this can happen in OS/2
11 * TODO: Does NOT work for sharing semaphores between processes!!
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#include <os2wrap.h>
36#include <win32type.h>
37#include <win32api.h>
38#include <winconst.h>
39#else
40#include <os2win.h>
41#endif
42#include <stdlib.h>
43#include <string.h>
44#include "unicode.h"
45#include "misc.h"
46
47#include "HandleManager.H"
48#include "HMSemaphore.h"
49#include "oslibdos.h"
50
51#define DBG_LOCALLOG DBG_hmsemaphore
52#include "dbglocal.h"
53
54#ifndef DCE_AUTORESET
55#define DCE_AUTORESET 0x1000 /* DosCreateEventSem option to auto-reset */
56 /* event semaphore on post. */
57#define DCE_POSTONE 0x0800 /* DosCreateEventSem option to post only */
58 /* waiter and auto-reset the semaphore when*/
59 /* there are multiple waiters. */
60#endif
61
62
63/*****************************************************************************
64 * Defines *
65 *****************************************************************************/
66
67/*****************************************************************************
68 * Structures *
69 *****************************************************************************/
70
71/*****************************************************************************
72 * Local Prototypes *
73 *****************************************************************************/
74
75
76/*****************************************************************************
77 * Name : HMCreateSemaphore
78 * Purpose : router function for CreateSemaphore
79 * Parameters:
80 * Variables :
81 * Result :
82 * Remark :
83 * Status :
84 *
85 * Author : Patrick Haller [Tue, 1999/07/06 20:44]
86 *****************************************************************************/
87
88DWORD HMDeviceSemaphoreClass::CreateSemaphore(PHMHANDLEDATA pHMHandleData,
89 LPSECURITY_ATTRIBUTES lpsa,
90 LONG lInitialCount,
91 LONG lMaximumCount,
92 LPCTSTR lpszSemaphoreName)
93{
94#ifdef USE_OS2SEMAPHORES
95 APIRET rc;
96 HEV hev;
97 char szSemName[CCHMAXPATH];
98
99
100 dprintf(("KERNEL32: HandleManager::Semaphore::CreateSemaphore(%08xh,%08xh,%08xh,%08xh,%s)\n",
101 pHMHandleData,
102 lpsa,
103 lInitialCount,
104 lMaximumCount,
105 lpszSemaphoreName));
106
107 if(lMaximumCount <= 0 || lInitialCount < 0 || lInitialCount > lMaximumCount) {
108 dprintf(("ERROR: invalid parameter"));
109 return ERROR_INVALID_PARAMETER_W;
110 }
111
112 if(lpszSemaphoreName) {
113 strcpy(szSemName, "\\SEM32\\");
114 strcat(szSemName, lpszSemaphoreName);
115 lpszSemaphoreName = szSemName;
116 }
117 //Manual reset means all threads waiting on the event semaphore will be
118 //unblocked and the app must manually reset the event semaphore
119 //Automatic reset -> only one waiting thread unblocked & state reset
120 rc = DosCreateEventSem(lpszSemaphoreName, &hev, DCE_POSTONE, lInitialCount);
121
122 if(rc) {
123 dprintf(("DosCreateEventSem %x failed with rc %d", pHMHandleData->hHMHandle, rc));
124 pHMHandleData->hHMHandle = 0;
125 return error2WinError(rc);
126 }
127 pHMHandleData->dwAccess = SEMAPHORE_ALL_ACCESS_W;
128 pHMHandleData->dwFlags = lMaximumCount;
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 dprintf(("KERNEL32: HandleManager::Semaphore::OpenSemaphore(%08xh,%08xh,%s)\n",
179 pHMHandleData,
180 fInheritHandle,
181 lpszSemaphoreName));
182
183 if(lpszSemaphoreName == NULL) {
184 pHMHandleData->hHMHandle = 0;
185 return ERROR_INVALID_PARAMETER_W;
186 }
187
188 strcpy(szSemName, "\\SEM32\\");
189 strcat(szSemName, lpszSemaphoreName);
190 rc = DosOpenEventSem(szSemName, &hev);
191 if(rc) {
192 dprintf(("DosOpenEventSem %x failed with rc %d", pHMHandleData->hHMHandle, rc));
193 pHMHandleData->hHMHandle = 0;
194 return error2WinError(rc);
195 }
196 pHMHandleData->hHMHandle = hev;
197 return ERROR_SUCCESS_W;
198#else
199 HANDLE hOpen32;
200
201 dprintf(("KERNEL32: HandleManager::Semaphore::OpenSemaphore(%08xh,%08xh,%s)\n",
202 pHMHandleData,
203 fInheritHandle,
204 lpszSemaphoreName));
205
206 hOpen32 = O32_OpenSemaphore(pHMHandleData->dwAccess, // call Open32
207 fInheritHandle,
208 lpszSemaphoreName);
209
210 if (0 != hOpen32) // check success
211 {
212 pHMHandleData->hHMHandle = hOpen32; // save handle
213 return (NO_ERROR);
214 }
215 else
216 return (O32_GetLastError());
217#endif
218}
219
220/*****************************************************************************
221 * Name : HMDeviceEventClass::CloseHandle
222 * Purpose : close the handle
223 * Parameters: PHMHANDLEDATA pHMHandleData
224 * Variables :
225 * Result : API returncode
226 * Remark :
227 * Status :
228 *
229 * Author :
230 *****************************************************************************/
231
232#ifdef USE_OS2SEMAPHORES
233BOOL HMDeviceSemaphoreClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
234{
235 APIRET rc;
236
237 if(pHMHandleData->hHMHandle) {
238 rc = DosCloseEventSem((HEV)pHMHandleData->hHMHandle);
239 if(rc) {
240 dprintf(("DosCloseEventSem %x failed with rc %d", pHMHandleData->hHMHandle, rc));
241 SetLastError(error2WinError(rc));
242 return FALSE;
243 }
244 }
245 return TRUE;
246}
247#endif
248
249
250/*****************************************************************************
251 * Name : HMDeviceEventClass::DuplicateHandle
252 * Purpose :
253 * Parameters:
254 * various parameters as required
255 * Variables :
256 * Result :
257 * Remark : the standard behaviour is to return an error code for non-
258 * existant request codes
259 * Status :
260 *
261 * Author :
262 *****************************************************************************/
263#ifdef USE_OS2SEMAPHORES
264BOOL HMDeviceSemaphoreClass::DuplicateHandle(PHMHANDLEDATA pHMHandleData, HANDLE srcprocess,
265 PHMHANDLEDATA pHMSrcHandle,
266 HANDLE destprocess,
267 PHANDLE desthandle,
268 DWORD fdwAccess,
269 BOOL fInherit,
270 DWORD fdwOptions,
271 DWORD fdwOdinOptions)
272{
273 APIRET rc;
274 HEV hev;
275
276 dprintf(("KERNEL32:HandleManager::DuplicateHandle %s(%08x,%08x,%08x,%08x,%08x)",
277 lpHMDeviceName,
278 pHMHandleData,
279 srcprocess, pHMSrcHandle, destprocess, desthandle));
280
281 if(srcprocess != destprocess) {
282 DebugInt3();
283 SetLastError(ERROR_ACCESS_DENIED_W);
284 return FALSE;
285 }
286 hev = (HEV)pHMSrcHandle->hHMHandle;
287 rc = DosOpenEventSem(NULL, &hev);
288 if(rc) {
289 dprintf(("DosOpenEventSem %x failed with rc %d", pHMSrcHandle->hHMHandle, rc));
290 pHMHandleData->hHMHandle = 0;
291 SetLastError(error2WinError(rc));
292 return FALSE;
293 }
294 pHMHandleData->dwAccess = fdwAccess;
295 pHMHandleData->dwFlags = pHMSrcHandle->dwFlags; //lMaximumCount;
296 pHMHandleData->hHMHandle = hev;
297 SetLastError(ERROR_SUCCESS_W);
298 return TRUE;
299}
300#endif
301
302/*****************************************************************************
303 * Name : HMReleaseSemaphore
304 * Purpose : router function for ReleaseSemaphore
305 * Parameters:
306 * Variables :
307 * Result :
308 * Remark :
309 * Status :
310 *
311 * Author : Patrick Haller [Tue, 1999/07/06 20:44]
312 *****************************************************************************/
313
314BOOL HMDeviceSemaphoreClass::ReleaseSemaphore(PHMHANDLEDATA pHMHandleData,
315 LONG cReleaseCount,
316 LPLONG lpPreviousCount)
317{
318#ifdef USE_OS2SEMAPHORES
319 APIRET rc;
320 ULONG count;
321
322 dprintf2(("KERNEL32: HandleManager::Semaphore::ReleaseSemaphore(%08xh,%08xh,%08xh)\n",
323 pHMHandleData->hHMHandle,
324 cReleaseCount,
325 lpPreviousCount));
326
327 if(!(pHMHandleData->dwAccess & SEMAPHORE_MODIFY_STATE_W) )
328 {
329 dprintf(("ERROR: Access denied!!"));
330 SetLastError(ERROR_ACCESS_DENIED_W);
331 return FALSE;
332 }
333
334 rc = DosResetEventSem(pHMHandleData->hHMHandle, &count);
335 if(rc) {
336 dprintf(("DosResetEventSem %x failed with rc %d", pHMHandleData->hHMHandle, rc));
337 SetLastError(error2WinError(rc));
338 return FALSE;
339 }
340 SetLastError(ERROR_SUCCESS_W);
341 return TRUE;
342#else
343 dprintf(("KERNEL32: HandleManager::Semaphore::ReleaseSemaphore(%08xh,%08xh,%08xh)\n",
344 pHMHandleData->hHMHandle,
345 cReleaseCount,
346 lpPreviousCount));
347
348 return (O32_ReleaseSemaphore(pHMHandleData->hHMHandle,
349 cReleaseCount,
350 lpPreviousCount));
351#endif
352}
353
Note: See TracBrowser for help on using the repository browser.