VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/os2/sems-os2.cpp@ 25711

Last change on this file since 25711 was 25711, checked in by vboxsync, 15 years ago

iprt: RTSemMutex order validation.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 9.2 KB
Line 
1/* $Id: sems-os2.cpp 25711 2010-01-11 11:15:04Z vboxsync $ */
2/** @file
3 * IPRT - Semaphores, OS/2.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 *
26 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31
32/*******************************************************************************
33* Header Files *
34*******************************************************************************/
35#define INCL_DOSSEMAPHORES
36#define INCL_ERRORS
37#include <os2.h>
38#undef RT_MAX
39
40#include <iprt/semaphore.h>
41#include <iprt/assert.h>
42#include <iprt/err.h>
43
44
45/** Converts semaphore to OS/2 handle. */
46#define SEM2HND(Sem) ((LHANDLE)(uintptr_t)Sem)
47
48
49/* Undefine debug mappings. */
50#undef RTSemMutexRequest
51#undef RTSemMutexRequestNoResume
52
53
54RTDECL(int) RTSemEventCreate(PRTSEMEVENT pEventSem)
55{
56 /*
57 * Create the semaphore.
58 * (Auto reset, not signaled, private event object.)
59 */
60 HEV hev;
61 int rc = DosCreateEventSem(NULL, &hev, DCE_AUTORESET | DCE_POSTONE, 0);
62 if (!rc)
63 {
64 *pEventSem = (RTSEMEVENT)(void *)hev;
65 return VINF_SUCCESS;
66 }
67 return RTErrConvertFromOS2(rc);
68}
69
70
71RTDECL(int) RTSemEventDestroy(RTSEMEVENT EventSem)
72{
73 if (EventSem == NIL_RTSEMEVENT) /* don't bitch */
74 return VERR_INVALID_HANDLE;
75
76 /*
77 * Close semaphore handle.
78 */
79 int rc = DosCloseEventSem(SEM2HND(EventSem));
80 if (!rc)
81 return VINF_SUCCESS;
82 AssertMsgFailed(("Destroy EventSem %p failed, rc=%d\n", EventSem, rc));
83 return RTErrConvertFromOS2(rc);
84}
85
86
87RTDECL(int) RTSemEventWaitNoResume(RTSEMEVENT EventSem, unsigned cMillies)
88{
89 /*
90 * Wait for condition.
91 */
92 int rc = DosWaitEventSem(SEM2HND(EventSem), cMillies == RT_INDEFINITE_WAIT ? SEM_INDEFINITE_WAIT : cMillies);
93 switch (rc)
94 {
95 case NO_ERROR: return VINF_SUCCESS;
96 case ERROR_SEM_TIMEOUT:
97 case ERROR_TIMEOUT: return VERR_TIMEOUT;
98 case ERROR_INTERRUPT: return VERR_INTERRUPTED;
99 default:
100 {
101 AssertMsgFailed(("Wait on EventSem %p failed, rc=%d\n", EventSem, rc));
102 return RTErrConvertFromOS2(rc);
103 }
104 }
105}
106
107
108RTDECL(int) RTSemEventSignal(RTSEMEVENT EventSem)
109{
110 /*
111 * Signal the object.
112 */
113 int rc = DosPostEventSem(SEM2HND(EventSem));
114 switch (rc)
115 {
116 case NO_ERROR:
117 case ERROR_ALREADY_POSTED:
118 case ERROR_TOO_MANY_POSTS:
119 return VINF_SUCCESS;
120 default:
121 return RTErrConvertFromOS2(rc);
122 }
123}
124
125
126RTDECL(void) RTSemEventSetSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
127{
128/** @todo implement RTSemEventSetSignaller and friends for OS/2 */
129}
130
131
132RTDECL(void) RTSemEventAddSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
133{
134
135}
136
137
138RTDECL(void) RTSemEventRemoveSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
139{
140
141}
142
143
144
145
146RTDECL(int) RTSemEventMultiCreate(PRTSEMEVENTMULTI pEventMultiSem)
147{
148 /*
149 * Create the semaphore.
150 * (Manual reset, not signaled, private event object.)
151 */
152 HEV hev;
153 int rc = DosCreateEventSem(NULL, &hev, 0, FALSE);
154 if (!rc)
155 {
156 *pEventMultiSem = (RTSEMEVENTMULTI)(void *)hev;
157 return VINF_SUCCESS;
158 }
159 return RTErrConvertFromOS2(rc);
160}
161
162
163RTDECL(int) RTSemEventMultiDestroy(RTSEMEVENTMULTI EventMultiSem)
164{
165 /*
166 * Close semaphore handle.
167 */
168 int rc = DosCloseEventSem(SEM2HND(EventMultiSem));
169 if (!rc)
170 return VINF_SUCCESS;
171 AssertMsgFailed(("Destroy EventMultiSem %p failed, rc=%d\n", EventMultiSem, rc));
172 return RTErrConvertFromOS2(rc);
173}
174
175
176RTDECL(int) RTSemEventMultiSignal(RTSEMEVENTMULTI EventMultiSem)
177{
178 /*
179 * Signal the object.
180 */
181 int rc = DosPostEventSem(SEM2HND(EventMultiSem));
182 switch (rc)
183 {
184 case NO_ERROR:
185 case ERROR_ALREADY_POSTED:
186 case ERROR_TOO_MANY_POSTS:
187 return VINF_SUCCESS;
188 default:
189 return RTErrConvertFromOS2(rc);
190 }
191}
192
193
194RTDECL(int) RTSemEventMultiReset(RTSEMEVENTMULTI EventMultiSem)
195{
196 /*
197 * Reset the object.
198 */
199 ULONG ulIgnore;
200 int rc = DosResetEventSem(SEM2HND(EventMultiSem), &ulIgnore);
201 switch (rc)
202 {
203 case NO_ERROR:
204 case ERROR_ALREADY_RESET:
205 return VINF_SUCCESS;
206 default:
207 return RTErrConvertFromOS2(rc);
208 }
209}
210
211
212RTDECL(int) RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies)
213{
214 /*
215 * Wait for condition.
216 */
217 int rc = DosWaitEventSem(SEM2HND(EventMultiSem), cMillies == RT_INDEFINITE_WAIT ? SEM_INDEFINITE_WAIT : cMillies);
218 switch (rc)
219 {
220 case NO_ERROR: return VINF_SUCCESS;
221 case ERROR_SEM_TIMEOUT:
222 case ERROR_TIMEOUT: return VERR_TIMEOUT;
223 case ERROR_INTERRUPT: return VERR_INTERRUPTED;
224 default:
225 {
226 AssertMsgFailed(("Wait on EventMultiSem %p failed, rc=%d\n", EventMultiSem, rc));
227 return RTErrConvertFromOS2(rc);
228 }
229 }
230}
231
232
233
234
235#undef RTSemMutexCreate
236RTDECL(int) RTSemMutexCreate(PRTSEMMUTEX phMutexSem)
237{
238 return RTSemMutexCreateEx(phMutexSem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, NULL);
239}
240
241
242RTDECL(int) RTSemMutexCreateEx(PRTSEMMUTEX phMutexSem, uint32_t fFlags,
243 RTLOCKVALCLASS hClass, uint32_t uSubClass, const char *pszNameFmt, ...)
244{
245 AssertReturn(!(fFlags & ~RTSEMMUTEX_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER);
246
247 /*
248 * Create the semaphore.
249 */
250 HMTX hmtx;
251 int rc = DosCreateMutexSem(NULL, &hmtx, 0, FALSE);
252 if (!rc)
253 {
254 /** @todo implement lock validation of OS/2 mutex semaphores. */
255 *phMutexSem = (RTSEMMUTEX)(void *)hmtx;
256 return VINF_SUCCESS;
257 }
258
259 return RTErrConvertFromOS2(rc);
260}
261
262
263RTDECL(int) RTSemMutexDestroy(RTSEMMUTEX MutexSem)
264{
265 /*
266 * Close semaphore handle.
267 */
268 int rc = DosCloseMutexSem(SEM2HND(MutexSem));
269 if (!rc)
270 return VINF_SUCCESS;
271 AssertMsgFailed(("Destroy MutexSem %p failed, rc=%d\n", MutexSem, rc));
272 return RTErrConvertFromOS2(rc);
273}
274
275
276
277RTDECL(uint32_t) RTSemMutexSetSubClass(RTSEMMUTEX hMutexSem, uint32_t uSubClass)
278{
279#if 0 /** @todo def RTSEMMUTEX_STRICT */
280 /*
281 * Validate.
282 */
283 RTSEMMUTEXINTERNAL *pThis = hMutexSem;
284 AssertPtrReturn(pThis, RTLOCKVAL_SUB_CLASS_INVALID);
285 AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, RTLOCKVAL_SUB_CLASS_INVALID);
286
287 return RTLockValidatorRecExclSetSubClass(&pThis->ValidatorRec, uSubClass);
288#else
289 return RTLOCKVAL_SUB_CLASS_INVALID;
290#endif
291}
292
293
294RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies)
295{
296 /*
297 * Lock mutex semaphore.
298 */
299 int rc = DosRequestMutexSem(SEM2HND(MutexSem), cMillies == RT_INDEFINITE_WAIT ? SEM_INDEFINITE_WAIT : cMillies);
300 switch (rc)
301 {
302 case NO_ERROR: return VINF_SUCCESS;
303 case ERROR_SEM_TIMEOUT:
304 case ERROR_TIMEOUT: return VERR_TIMEOUT;
305 case ERROR_INTERRUPT: return VERR_INTERRUPTED;
306 case ERROR_SEM_OWNER_DIED: return VERR_SEM_OWNER_DIED;
307 default:
308 {
309 AssertMsgFailed(("Wait on MutexSem %p failed, rc=%d\n", MutexSem, rc));
310 return RTErrConvertFromOS2(rc);
311 }
312 }
313}
314
315RTDECL(int) RTSemMutexRelease(RTSEMMUTEX MutexSem)
316{
317 /*
318 * Unlock mutex semaphore.
319 */
320 int rc = DosReleaseMutexSem(SEM2HND(MutexSem));
321 if (!rc)
322 return VINF_SUCCESS;
323 AssertMsgFailed(("Release MutexSem %p failed, rc=%d\n", MutexSem, rc));
324 return RTErrConvertFromOS2(rc);
325}
326
327
328RTDECL(bool) RTSemMutexIsOwned(RTSEMMUTEX hMutex);
329{
330 /*
331 * Unlock mutex semaphore.
332 */
333 PID pid;
334 TID tid;
335 ULONG cRecursions;
336 int rc = DosQueryMutexSem(SEM2HND(MutexSem), &pid, &tid, &cRecursions);
337 if (!rc)
338 return cRecursions != 0;
339 AssertMsgFailed(("DosQueryMutexSem %p failed, rc=%d\n", MutexSem, rc));
340 return rc == ERROR_SEM_OWNER_DIED;
341}
342
343
344RTDECL(void) RTSemEventMultiSetSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread)
345{
346 /** @todo implement RTSemEventMultiSetSignaller on OS/2 */
347}
348
349
350RTDECL(void) RTSemEventMultiAddSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread)
351{
352}
353
354
355RTDECL(void) RTSemEventMultiRemoveSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread)
356{
357}
358
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette