Changeset 25653 in vbox for trunk/src/VBox/Runtime/r3
- Timestamp:
- Jan 5, 2010 3:22:29 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/win/semevent-win.cpp
r25640 r25653 37 37 38 38 #include <iprt/semaphore.h> 39 #include <iprt/thread.h> 39 #include "internal/iprt.h" 40 41 #include <iprt/asm.h> 40 42 #include <iprt/assert.h> 41 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" 42 48 #include "internal/strict.h" 43 49 … … 46 52 * Defined Constants And Macros * 47 53 *******************************************************************************/ 48 /** Converts semaphore to win32 handle. */ 49 #define SEM2HND(Sem) ((HANDLE)(uintptr_t)Sem) 54 struct 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 }; 50 67 51 68 … … 57 74 RTDECL(int) RTSemEventCreate(PRTSEMEVENT pEventSem) 58 75 { 76 struct RTSEMEVENTINTERNAL *pThis = (struct RTSEMEVENTINTERNAL *)RTMemAlloc(sizeof(*pThis)); 77 if (!pThis) 78 return VERR_NO_MEMORY; 79 59 80 /* 60 81 * Create the semaphore. 61 82 * (Auto reset, not signaled, private event object.) 62 83 */ 63 HANDLE hev = CreateEvent(NULL, FALSE, FALSE, NULL); 64 if (hev) 65 { 66 *pEventSem = (RTSEMEVENT)(void *)hev; 67 Assert(*pEventSem != NIL_RTSEMEVENT); 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_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_ANY, 91 "RTSemEvent", pThis, true /*fSignaller*/); 92 pThis->fEverHadSignallers = false; 93 #endif 94 95 *pEventSem = pThis; 68 96 return VINF_SUCCESS; 69 97 } 70 return RTErrConvertFromWin32(GetLastError()); 98 99 DWORD dwErr = GetLastError(); 100 RTMemFree(pThis); 101 return RTErrConvertFromWin32(dwErr); 71 102 } 72 103 … … 74 105 RTDECL(int) RTSemEventDestroy(RTSEMEVENT EventSem) 75 106 { 76 if (EventSem == NIL_RTSEMEVENT) /* don't bitch */ 107 struct RTSEMEVENTINTERNAL *pThis = EventSem; 108 if (pThis == NIL_RTSEMEVENT) /* don't bitch */ 77 109 return VERR_INVALID_HANDLE; 78 79 /* 80 * Close semaphore handle. 81 */ 82 if (CloseHandle(SEM2HND(EventSem))) 83 return VINF_SUCCESS; 84 AssertMsgFailed(("Destroy EventSem %p failed, lasterr=%d\n", EventSem, GetLastError())); 85 return RTErrConvertFromWin32(GetLastError()); 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; 86 134 } 87 135 … … 89 137 RTDECL(int) RTSemEventWaitNoResume(RTSEMEVENT EventSem, unsigned cMillies) 90 138 { 139 PCRTLOCKVALSRCPOS pSrcPos = NULL; 140 141 /* 142 * Validate input. 143 */ 144 struct RTSEMEVENTINTERNAL *pThis = EventSem; 145 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 146 AssertReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, VERR_INVALID_HANDLE); 147 91 148 /* 92 149 * Wait for condition. 93 150 */ 94 int rc = WaitForSingleObjectEx(SEM2HND(EventSem), cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies, TRUE); 151 #ifdef RTSEMEVENT_STRICT 152 RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt(); 153 if (pThis->fEverHadSignallers) 154 { 155 int rc9 = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false, 156 RTTHREADSTATE_EVENT, true); 157 if (RT_FAILURE(rc9)) 158 return rc9; 159 } 160 #else 161 RTTHREAD hThreadSelf = RTThreadSelf(); 162 #endif 163 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT, true); 164 DWORD rc = WaitForSingleObjectEx(pThis->hev, 165 cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies, 166 TRUE /*fAlertable*/); 167 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT); 95 168 switch (rc) 96 169 { … … 100 173 case WAIT_ABANDONED: return VERR_SEM_OWNER_DIED; 101 174 default: 175 AssertMsgFailed(("%u\n", rc)); 176 case WAIT_FAILED: 102 177 { 103 178 AssertMsgFailed(("Wait on EventSem %p failed, rc=%d lasterr=%d\n", EventSem, rc, GetLastError())); … … 116 191 { 117 192 /* 193 * Validate input. 194 */ 195 struct RTSEMEVENTINTERNAL *pThis = EventSem; 196 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 197 AssertReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, VERR_INVALID_HANDLE); 198 199 #ifdef RTSEMEVENT_STRICT 200 if (pThis->fEverHadSignallers) 201 { 202 int rc9 = RTLockValidatorRecSharedCheckSignaller(&pThis->Signallers, NIL_RTTHREAD); 203 if (RT_FAILURE(rc9)) 204 return rc9; 205 } 206 #endif 207 208 /* 118 209 * Signal the object. 119 210 */ 120 if (SetEvent( SEM2HND(EventSem)))211 if (SetEvent(pThis->hev)) 121 212 return VINF_SUCCESS; 122 AssertMsgFailed(("Signaling EventSem %p failed, lasterr=%d\n", EventSem, GetLastError())); 123 return RTErrConvertFromWin32(GetLastError()); 213 DWORD dwErr = GetLastError(); 214 AssertMsgFailed(("Signaling EventSem %p failed, lasterr=%d\n", pThis, dwErr)); 215 return RTErrConvertFromWin32(dwErr); 124 216 } 125 217 … … 127 219 RTDECL(void) RTSemEventSetSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread) 128 220 { 129 /** @todo implement RTSemEventSetSignaller and friends for NT. */ 221 #ifdef RTSEMEVENT_STRICT 222 struct RTSEMEVENTINTERNAL *pThis = hEventSem; 223 AssertPtrReturnVoid(pThis); 224 AssertReturnVoid(pThis->u32Magic == RTSEMEVENT_MAGIC); 225 226 ASMAtomicWriteBool(&pThis->fEverHadSignallers, true); 227 RTLockValidatorRecSharedResetOwner(&pThis->Signallers, hThread, NULL); 228 #endif 130 229 } 131 230 … … 133 232 RTDECL(void) RTSemEventAddSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread) 134 233 { 135 234 #ifdef RTSEMEVENT_STRICT 235 struct RTSEMEVENTINTERNAL *pThis = hEventSem; 236 AssertPtrReturnVoid(pThis); 237 AssertReturnVoid(pThis->u32Magic == RTSEMEVENT_MAGIC); 238 239 ASMAtomicWriteBool(&pThis->fEverHadSignallers, true); 240 RTLockValidatorRecSharedAddOwner(&pThis->Signallers, hThread, NULL); 241 #endif 136 242 } 137 243 … … 139 245 RTDECL(void) RTSemEventRemoveSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread) 140 246 { 141 142 } 143 247 #ifdef RTSEMEVENT_STRICT 248 struct RTSEMEVENTINTERNAL *pThis = hEventSem; 249 AssertPtrReturnVoid(pThis); 250 AssertReturnVoid(pThis->u32Magic == RTSEMEVENT_MAGIC); 251 252 RTLockValidatorRecSharedRemoveOwner(&pThis->Signallers, hThread); 253 #endif 254 } 255
Note:
See TracChangeset
for help on using the changeset viewer.