Changeset 25654 in vbox
- Timestamp:
- Jan 5, 2010 3:36:47 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/win/semeventmulti-win.cpp
r25640 r25654 2 2 /** @file 3 3 * IPRT - Multiple Release Event Semaphore, Windows. 4 * 5 * @remarks This file is identical to semevent-win.cpp except for the 2nd 6 * CreateEvent parameter, the reset function and the "Multi" infix. 4 7 */ 5 8 6 9 /* 7 * Copyright (C) 2006-20 09Sun Microsystems, Inc.10 * Copyright (C) 2006-2010 Sun Microsystems, Inc. 8 11 * 9 12 * This file is part of VirtualBox Open Source Edition (OSE), as … … 37 40 38 41 #include <iprt/semaphore.h> 39 #include <iprt/thread.h> 42 #include "internal/iprt.h" 43 44 #include <iprt/asm.h> 40 45 #include <iprt/assert.h> 41 46 #include <iprt/err.h> 47 #include <iprt/lockvalidator.h> 48 #include <iprt/mem.h> 49 #include <iprt/thread.h> 50 #include "internal/magics.h" 42 51 #include "internal/strict.h" 43 52 … … 46 55 * Defined Constants And Macros * 47 56 *******************************************************************************/ 48 /** Converts semaphore to win32 handle. */ 49 #define SEM2HND(Sem) ((HANDLE)(uintptr_t)Sem) 57 struct RTSEMEVENTMULTIINTERNAL 58 { 59 /** Magic value (RTSEMEVENTMULTI_MAGIC). */ 60 uint32_t u32Magic; 61 /** The event handle. */ 62 HANDLE hev; 63 #ifdef RTSEMEVENT_STRICT 64 /** Signallers. */ 65 RTLOCKVALRECSHRD Signallers; 66 /** Indicates that lock validation should be performed. */ 67 bool volatile fEverHadSignallers; 68 #endif 69 }; 50 70 51 71 … … 57 77 RTDECL(int) RTSemEventMultiCreate(PRTSEMEVENTMULTI pEventMultiSem) 58 78 { 79 struct RTSEMEVENTMULTIINTERNAL *pThis = (struct RTSEMEVENTMULTIINTERNAL *)RTMemAlloc(sizeof(*pThis)); 80 if (!pThis) 81 return VERR_NO_MEMORY; 82 59 83 /* 60 84 * Create the semaphore. 61 85 * (Manual reset, not signaled, private event object.) 62 86 */ 63 HANDLE hev = CreateEvent(NULL, TRUE, FALSE, NULL); 64 if (hev) 65 { 66 *pEventMultiSem = (RTSEMEVENTMULTI)(void *)hev; 87 pThis->hev = CreateEvent(NULL, TRUE, FALSE, NULL); 88 if (pThis->hev != NULL) /* not INVALID_HANDLE_VALUE */ 89 { 90 pThis->u32Magic = RTSEMEVENTMULTI_MAGIC; 91 #ifdef RTSEMEVENT_STRICT 92 RTLockValidatorRecSharedInit(&pThis->Signallers, 93 NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_ANY, 94 "RTSemEvent", pThis, true /*fSignaller*/); 95 pThis->fEverHadSignallers = false; 96 #endif 97 98 *pEventMultiSem = pThis; 67 99 return VINF_SUCCESS; 68 100 } 69 return RTErrConvertFromWin32(GetLastError()); 101 102 DWORD dwErr = GetLastError(); 103 RTMemFree(pThis); 104 return RTErrConvertFromWin32(dwErr); 70 105 } 71 106 … … 73 108 RTDECL(int) RTSemEventMultiDestroy(RTSEMEVENTMULTI EventMultiSem) 74 109 { 75 /* 76 * Close semaphore handle. 77 */ 78 if (CloseHandle(SEM2HND(EventMultiSem))) 110 struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem; 111 if (pThis == NIL_RTSEMEVENT) /* don't bitch */ 112 return VERR_INVALID_HANDLE; 113 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 114 AssertReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, VERR_INVALID_HANDLE); 115 116 /* 117 * Invalidate the handle and close the semaphore. 118 */ 119 int rc = VINF_SUCCESS; 120 AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, ~RTSEMEVENTMULTI_MAGIC, RTSEMEVENTMULTI_MAGIC), VERR_INVALID_HANDLE); 121 if (CloseHandle(pThis->hev)) 122 { 123 #ifdef RTSEMEVENT_STRICT 124 RTLockValidatorRecSharedDelete(&pThis->Signallers); 125 #endif 126 RTMemFree(pThis); 127 } 128 else 129 { 130 DWORD dwErr = GetLastError(); 131 rc = RTErrConvertFromWin32(dwErr); 132 AssertMsgFailed(("Destroy EventMultiSem %p failed, lasterr=%u (%Rrc)\n", pThis, dwErr, rc)); 133 /* Leak it. */ 134 } 135 136 return rc; 137 } 138 139 140 RTDECL(int) RTSemEventMultiSignal(RTSEMEVENTMULTI EventMultiSem) 141 { 142 /* 143 * Validate input. 144 */ 145 struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem; 146 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 147 AssertReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, VERR_INVALID_HANDLE); 148 149 #ifdef RTSEMEVENT_STRICT 150 if (pThis->fEverHadSignallers) 151 { 152 int rc9 = RTLockValidatorRecSharedCheckSignaller(&pThis->Signallers, NIL_RTTHREAD); 153 if (RT_FAILURE(rc9)) 154 return rc9; 155 } 156 #endif 157 158 /* 159 * Signal the object. 160 */ 161 if (SetEvent(pThis->hev)) 79 162 return VINF_SUCCESS; 80 AssertMsgFailed(("Destroy EventMultiSem %p failed, lasterr=%d\n", EventMultiSem, GetLastError())); 81 return RTErrConvertFromWin32(GetLastError()); 82 } 83 84 85 RTDECL(int) RTSemEventMultiSignal(RTSEMEVENTMULTI EventMultiSem) 86 { 87 /* 88 * Signal the object. 89 */ 90 if (SetEvent(SEM2HND(EventMultiSem))) 163 DWORD dwErr = GetLastError(); 164 AssertMsgFailed(("Signaling EventMultiSem %p failed, lasterr=%d\n", pThis, dwErr)); 165 return RTErrConvertFromWin32(dwErr); 166 } 167 168 169 RTDECL(int) RTSemEventMultiReset(RTSEMEVENTMULTI EventMultiSem) 170 { 171 /* 172 * Validate input. 173 */ 174 struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem; 175 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 176 AssertReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, VERR_INVALID_HANDLE); 177 178 /* 179 * Reset the object. 180 */ 181 if (ResetEvent(pThis->hev)) 91 182 return VINF_SUCCESS; 92 AssertMsgFailed(("Signaling EventMultiSem %p failed, lasterr=%d\n", EventMultiSem, GetLastError())); 93 return RTErrConvertFromWin32(GetLastError()); 94 } 95 96 97 RTDECL(int) RTSemEventMultiReset(RTSEMEVENTMULTI EventMultiSem) 98 { 99 /* 100 * Reset the object. 101 */ 102 if (ResetEvent(SEM2HND(EventMultiSem))) 103 return VINF_SUCCESS; 104 AssertMsgFailed(("Resetting EventMultiSem %p failed, lasterr=%d\n", EventMultiSem, GetLastError())); 105 return RTErrConvertFromWin32(GetLastError()); 183 DWORD dwErr = GetLastError(); 184 AssertMsgFailed(("Resetting EventMultiSem %p failed, lasterr=%d\n", pThis, dwErr)); 185 return RTErrConvertFromWin32(dwErr); 106 186 } 107 187 … … 109 189 RTDECL(int) RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies) 110 190 { 191 PCRTLOCKVALSRCPOS pSrcPos = NULL; 192 193 /* 194 * Validate input. 195 */ 196 struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem; 197 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 198 AssertReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, VERR_INVALID_HANDLE); 199 111 200 /* 112 201 * Wait for condition. 113 202 */ 114 int rc = WaitForSingleObjectEx(SEM2HND(EventMultiSem), cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies, TRUE); 203 #ifdef RTSEMEVENT_STRICT 204 RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt(); 205 if (pThis->fEverHadSignallers) 206 { 207 int rc9 = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false, 208 RTTHREADSTATE_EVENT_MULTI, true); 209 if (RT_FAILURE(rc9)) 210 return rc9; 211 } 212 #else 213 RTTHREAD hThreadSelf = RTThreadSelf(); 214 #endif 215 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT_MULTI, true); 216 DWORD rc = WaitForSingleObjectEx(pThis->hev, 217 cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies, 218 TRUE /*fAlertable*/); 219 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT_MULTI); 115 220 switch (rc) 116 221 { … … 120 225 case WAIT_ABANDONED: return VERR_SEM_OWNER_DIED; 121 226 default: 227 AssertMsgFailed(("%u\n", rc)); 228 case WAIT_FAILED: 122 229 { 123 AssertMsgFailed(("Wait on EventMultiSem %p failed, rc=%d lasterr=%d\n", EventMultiSem, rc, GetLastError()));230 AssertMsgFailed(("Wait on EventMultiSem %p failed, rc=%d lasterr=%d\n", pThis, rc, GetLastError())); 124 231 int rc2 = RTErrConvertFromWin32(GetLastError()); 125 232 if (rc2) … … 135 242 RTDECL(void) RTSemEventMultiSetSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread) 136 243 { 137 /** @todo implement RTSemEventMultiSetSignaller on Windows */ 244 #ifdef RTSEMEVENT_STRICT 245 struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem; 246 AssertPtrReturnVoid(pThis); 247 AssertReturnVoid(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC); 248 249 ASMAtomicWriteBool(&pThis->fEverHadSignallers, true); 250 RTLockValidatorRecSharedResetOwner(&pThis->Signallers, hThread, NULL); 251 #endif 138 252 } 139 253 … … 141 255 RTDECL(void) RTSemEventMultiAddSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread) 142 256 { 257 #ifdef RTSEMEVENT_STRICT 258 struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem; 259 AssertPtrReturnVoid(pThis); 260 AssertReturnVoid(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC); 261 262 ASMAtomicWriteBool(&pThis->fEverHadSignallers, true); 263 RTLockValidatorRecSharedAddOwner(&pThis->Signallers, hThread, NULL); 264 #endif 143 265 } 144 266 … … 146 268 RTDECL(void) RTSemEventMultiRemoveSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread) 147 269 { 148 } 149 270 #ifdef RTSEMEVENT_STRICT 271 struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem; 272 AssertPtrReturnVoid(pThis); 273 AssertReturnVoid(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC); 274 275 RTLockValidatorRecSharedRemoveOwner(&pThis->Signallers, hThread); 276 #endif 277 } 278
Note:
See TracChangeset
for help on using the changeset viewer.

