VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/win/semevent-win.cpp@ 25682

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

iprt,pdmcritsect: RTMSINTERVAL, RTLockValidatorClass* and some related renaming.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.3 KB
Line 
1/* $Id: semevent-win.cpp 25682 2010-01-07 15:23:30Z vboxsync $ */
2/** @file
3 * IPRT - Event Sempahore, Windows.
4 */
5
6/*
7 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. 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 LOG_GROUP RTLOGGROUP_SEMAPHORE
36#include <Windows.h>
37
38#include <iprt/semaphore.h>
39#include "internal/iprt.h"
40
41#include <iprt/asm.h>
42#include <iprt/assert.h>
43#include <iprt/err.h>
44#include <iprt/lockvalidator.h>
45#include <iprt/mem.h>
46#include <iprt/thread.h>
47#include "internal/magics.h"
48#include "internal/strict.h"
49
50
51/*******************************************************************************
52* Defined Constants And Macros *
53*******************************************************************************/
54struct RTSEMEVENTINTERNAL
55{
56 /** Magic value (RTSEMEVENT_MAGIC). */
57 uint32_t u32Magic;
58 /** The event handle. */
59 HANDLE hev;
60#ifdef RTSEMEVENT_STRICT
61 /** Signallers. */
62 RTLOCKVALRECSHRD Signallers;
63 /** Indicates that lock validation should be performed. */
64 bool volatile fEverHadSignallers;
65#endif
66};
67
68
69/* Undefine debug mappings. */
70#undef RTSemEventWait
71#undef RTSemEventWaitNoResume
72
73
74RTDECL(int) RTSemEventCreate(PRTSEMEVENT pEventSem)
75{
76 struct RTSEMEVENTINTERNAL *pThis = (struct RTSEMEVENTINTERNAL *)RTMemAlloc(sizeof(*pThis));
77 if (!pThis)
78 return VERR_NO_MEMORY;
79
80 /*
81 * Create the semaphore.
82 * (Auto reset, not signaled, private event object.)
83 */
84 pThis->hev = CreateEvent(NULL, FALSE, FALSE, NULL);
85 if (pThis->hev != NULL) /* not INVALID_HANDLE_VALUE */
86 {
87 pThis->u32Magic = RTSEMEVENT_MAGIC;
88#ifdef RTSEMEVENT_STRICT
89 RTLockValidatorRecSharedInit(&pThis->Signallers,
90 NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_ANY,
91 "RTSemEvent", pThis, true /*fSignaller*/);
92 pThis->fEverHadSignallers = false;
93#endif
94
95 *pEventSem = pThis;
96 return VINF_SUCCESS;
97 }
98
99 DWORD dwErr = GetLastError();
100 RTMemFree(pThis);
101 return RTErrConvertFromWin32(dwErr);
102}
103
104
105RTDECL(int) RTSemEventDestroy(RTSEMEVENT EventSem)
106{
107 struct RTSEMEVENTINTERNAL *pThis = EventSem;
108 if (pThis == NIL_RTSEMEVENT) /* don't bitch */
109 return VERR_INVALID_HANDLE;
110 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
111 AssertReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, VERR_INVALID_HANDLE);
112
113 /*
114 * Invalidate the handle and close the semaphore.
115 */
116 int rc = VINF_SUCCESS;
117 AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, ~RTSEMEVENT_MAGIC, RTSEMEVENT_MAGIC), VERR_INVALID_HANDLE);
118 if (CloseHandle(pThis->hev))
119 {
120#ifdef RTSEMEVENT_STRICT
121 RTLockValidatorRecSharedDelete(&pThis->Signallers);
122#endif
123 RTMemFree(pThis);
124 }
125 else
126 {
127 DWORD dwErr = GetLastError();
128 rc = RTErrConvertFromWin32(dwErr);
129 AssertMsgFailed(("Destroy EventSem %p failed, lasterr=%u (%Rrc)\n", pThis, dwErr, rc));
130 /* Leak it. */
131 }
132
133 return rc;
134}
135
136
137RTDECL(int) RTSemEventSignal(RTSEMEVENT EventSem)
138{
139 /*
140 * Validate input.
141 */
142 struct RTSEMEVENTINTERNAL *pThis = EventSem;
143 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
144 AssertReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, VERR_INVALID_HANDLE);
145
146#ifdef RTSEMEVENT_STRICT
147 if (pThis->fEverHadSignallers)
148 {
149 int rc9 = RTLockValidatorRecSharedCheckSignaller(&pThis->Signallers, NIL_RTTHREAD);
150 if (RT_FAILURE(rc9))
151 return rc9;
152 }
153#endif
154
155 /*
156 * Signal the object.
157 */
158 if (SetEvent(pThis->hev))
159 return VINF_SUCCESS;
160 DWORD dwErr = GetLastError();
161 AssertMsgFailed(("Signaling EventSem %p failed, lasterr=%d\n", pThis, dwErr));
162 return RTErrConvertFromWin32(dwErr);
163}
164
165
166/** Goto avoidance. */
167DECL_FORCE_INLINE(int) rtSemEventWaitHandleStatus(struct RTSEMEVENTINTERNAL *pThis, DWORD rc)
168{
169 switch (rc)
170 {
171 case WAIT_OBJECT_0: return VINF_SUCCESS;
172 case WAIT_TIMEOUT: return VERR_TIMEOUT;
173 case WAIT_IO_COMPLETION: return VERR_INTERRUPTED;
174 case WAIT_ABANDONED: return VERR_SEM_OWNER_DIED;
175 default:
176 AssertMsgFailed(("%u\n", rc));
177 case WAIT_FAILED:
178 {
179 int rc2 = RTErrConvertFromWin32(GetLastError());
180 AssertMsgFailed(("Wait on EventSem %p failed, rc=%d lasterr=%d\n", pThis, rc, GetLastError()));
181 if (rc2)
182 return rc2;
183
184 AssertMsgFailed(("WaitForSingleObject(event) -> rc=%d while converted lasterr=%d\n", rc, rc2));
185 return VERR_INTERNAL_ERROR;
186 }
187 }
188}
189
190
191RTDECL(int) RTSemEventWaitNoResume(RTSEMEVENT EventSem, unsigned cMillies)
192{
193 PCRTLOCKVALSRCPOS pSrcPos = NULL;
194
195 /*
196 * Validate input.
197 */
198 struct RTSEMEVENTINTERNAL *pThis = EventSem;
199 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
200 AssertReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, VERR_INVALID_HANDLE);
201
202 /*
203 * Wait for condition.
204 */
205#ifdef RTSEMEVENT_STRICT
206 RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
207 if (pThis->fEverHadSignallers)
208 {
209 DWORD rc = WaitForSingleObjectEx(pThis->hev,
210 0 /*Timeout*/,
211 TRUE /*fAlertable*/);
212 if (rc != WAIT_TIMEOUT || cMillies == 0)
213 return rtSemEventWaitHandleStatus(pThis, rc);
214 int rc9 = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false,
215 RTTHREADSTATE_EVENT, true);
216 if (RT_FAILURE(rc9))
217 return rc9;
218 }
219#else
220 RTTHREAD hThreadSelf = RTThreadSelf();
221#endif
222 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT, true);
223 DWORD rc = WaitForSingleObjectEx(pThis->hev,
224 cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies,
225 TRUE /*fAlertable*/);
226 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT);
227 return rtSemEventWaitHandleStatus(pThis, rc);
228}
229
230
231RTDECL(void) RTSemEventSetSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
232{
233#ifdef RTSEMEVENT_STRICT
234 struct RTSEMEVENTINTERNAL *pThis = hEventSem;
235 AssertPtrReturnVoid(pThis);
236 AssertReturnVoid(pThis->u32Magic == RTSEMEVENT_MAGIC);
237
238 ASMAtomicWriteBool(&pThis->fEverHadSignallers, true);
239 RTLockValidatorRecSharedResetOwner(&pThis->Signallers, hThread, NULL);
240#endif
241}
242
243
244RTDECL(void) RTSemEventAddSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
245{
246#ifdef RTSEMEVENT_STRICT
247 struct RTSEMEVENTINTERNAL *pThis = hEventSem;
248 AssertPtrReturnVoid(pThis);
249 AssertReturnVoid(pThis->u32Magic == RTSEMEVENT_MAGIC);
250
251 ASMAtomicWriteBool(&pThis->fEverHadSignallers, true);
252 RTLockValidatorRecSharedAddOwner(&pThis->Signallers, hThread, NULL);
253#endif
254}
255
256
257RTDECL(void) RTSemEventRemoveSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
258{
259#ifdef RTSEMEVENT_STRICT
260 struct RTSEMEVENTINTERNAL *pThis = hEventSem;
261 AssertPtrReturnVoid(pThis);
262 AssertReturnVoid(pThis->u32Magic == RTSEMEVENT_MAGIC);
263
264 RTLockValidatorRecSharedRemoveOwner(&pThis->Signallers, hThread);
265#endif
266}
267
Note: See TracBrowser for help on using the repository browser.

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