Changeset 25640 in vbox for trunk/src/VBox/Runtime/r3/posix
- Timestamp:
- Jan 4, 2010 4:44:23 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/posix/semeventmulti-posix.cpp
r25636 r25640 33 33 *******************************************************************************/ 34 34 #include <iprt/semaphore.h> 35 #include "internal/iprt.h" 36 37 #include <iprt/asm.h> 35 38 #include <iprt/assert.h> 36 #include <iprt/alloc.h>37 #include <iprt/asm.h>38 39 #include <iprt/err.h> 40 #include <iprt/lockvalidator.h> 41 #include <iprt/mem.h> 42 43 #include "internal/strict.h" 39 44 40 45 #include <errno.h> … … 61 66 /** Number of waiters. */ 62 67 volatile uint32_t cWaiters; 68 #ifdef RTSEMEVENTMULTI_STRICT 69 /** Signallers. */ 70 RTLOCKVALRECSHRD Signallers; 71 /** Indicates that lock validation should be performed. */ 72 bool volatile fEverHadSignallers; 73 #endif 63 74 }; 64 75 … … 73 84 /** @} */ 74 85 75 76 77 /**78 * Validate an event multi semaphore handle passed to one of the interface.79 *80 * @returns true if valid.81 * @returns false if invalid.82 * @param pThis Pointer to the event semaphore to validate.83 */84 inline bool rtsemEventMultiValid(struct RTSEMEVENTMULTIINTERNAL *pThis)85 {86 if ((uintptr_t)pThis < 0x10000)87 return false;88 89 uint32_t u32 = pThis->u32State; /* this is volatile, so a explicit read like this is needed. */90 if ( u32 != EVENTMULTI_STATE_NOT_SIGNALED91 && u32 != EVENTMULTI_STATE_SIGNALED)92 return false;93 94 return true;95 }96 86 97 87 … … 131 121 ASMAtomicXchgU32(&pThis->u32State, EVENTMULTI_STATE_NOT_SIGNALED); 132 122 ASMAtomicXchgU32(&pThis->cWaiters, 0); 123 #ifdef RTSEMEVENTMULTI_STRICT 124 RTLockValidatorRecSharedInit(&pThis->Signallers, 125 NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_ANY, 126 "RTSemEvent", pThis, true /*fSignaller*/); 127 pThis->fEverHadSignallers = false; 128 #endif 133 129 134 130 *pEventMultiSem = pThis; … … 159 155 * Validate handle. 160 156 */ 161 if (!rtsemEventMultiValid(EventMultiSem)) 162 { 163 AssertMsgFailed(("Invalid handle %p!\n", EventMultiSem)); 164 return VERR_INVALID_HANDLE; 165 } 157 struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem; 158 if (pThis == NIL_RTSEMEVENTMULTI) 159 return VINF_SUCCESS; 160 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 161 uint32_t u32 = pThis->u32State; 162 AssertReturn(u32 == EVENTMULTI_STATE_NOT_SIGNALED || u32 == EVENTMULTI_STATE_SIGNALED, VERR_INVALID_HANDLE); 166 163 167 164 /* 168 165 * Abort all waiters forcing them to return failure. 169 166 */ 170 struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem;171 167 int rc; 172 168 for (int i = 30; i > 0; i--) … … 205 201 * Free the semaphore memory and be gone. 206 202 */ 203 #ifdef RTSEMEVENTMULTI_STRICT 204 RTLockValidatorRecSharedDelete(&pThis->Signallers); 205 #endif 207 206 RTMemFree(pThis); 208 207 return VINF_SUCCESS; … … 215 214 * Validate input. 216 215 */ 217 if (!rtsemEventMultiValid(EventMultiSem)) 218 { 219 AssertMsgFailed(("Invalid handle %p!\n", EventMultiSem)); 220 return VERR_INVALID_HANDLE; 221 } 216 struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem; 217 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 218 uint32_t u32 = pThis->u32State; 219 AssertReturn(u32 == EVENTMULTI_STATE_NOT_SIGNALED || u32 == EVENTMULTI_STATE_SIGNALED, VERR_INVALID_HANDLE); 220 221 #ifdef RTSEMEVENTMULTI_STRICT 222 if (pThis->fEverHadSignallers) 223 { 224 int rc9 = RTLockValidatorRecSharedCheckSignaller(&pThis->Signallers, NIL_RTTHREAD); 225 if (RT_FAILURE(rc9)) 226 return rc9; 227 } 228 #endif 222 229 223 230 /* 224 231 * Lock the mutex semaphore. 225 232 */ 226 struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem;227 233 int rc = pthread_mutex_lock(&pThis->Mutex); 228 234 if (rc) … … 268 274 * Validate input. 269 275 */ 270 if (!rtsemEventMultiValid(EventMultiSem)) 271 { 272 AssertMsgFailed(("Invalid handle %p!\n", EventMultiSem)); 273 return VERR_INVALID_HANDLE; 274 } 276 struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem; 277 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 278 uint32_t u32 = pThis->u32State; 279 AssertReturn(u32 == EVENTMULTI_STATE_NOT_SIGNALED || u32 == EVENTMULTI_STATE_SIGNALED, VERR_INVALID_HANDLE); 275 280 276 281 /* 277 282 * Lock the mutex semaphore. 278 283 */ 279 struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem;280 284 int rc = pthread_mutex_lock(&pThis->Mutex); 281 285 if (rc) … … 310 314 static int rtSemEventMultiWait(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies, bool fAutoResume) 311 315 { 316 PCRTLOCKVALSRCPOS pSrcPos = NULL; 317 312 318 /* 313 319 * Validate input. 314 320 */ 315 if (!rtsemEventMultiValid(EventMultiSem)) 316 { 317 AssertMsgFailed(("Invalid handle %p!\n", EventMultiSem)); 318 return VERR_INVALID_HANDLE; 319 } 321 struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem; 322 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 323 uint32_t u32 = pThis->u32State; 324 AssertReturn(u32 == EVENTMULTI_STATE_NOT_SIGNALED || u32 == EVENTMULTI_STATE_SIGNALED, VERR_INVALID_HANDLE); 320 325 321 326 /* 322 327 * Timed or indefinite wait? 323 328 */ 324 struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem;325 329 if (cMillies == RT_INDEFINITE_WAIT) 326 330 { … … 352 356 353 357 /* wait */ 358 #ifdef RTSEMEVENTMULTI_STRICT 359 RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt(); 360 if (pThis->fEverHadSignallers) 361 { 362 rc = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false, 363 RTTHREADSTATE_EVENT_MULTI, true); 364 if (RT_FAILURE(rc)) 365 { 366 ASMAtomicDecU32(&pThis->cWaiters); 367 pthread_mutex_unlock(&pThis->Mutex); 368 return rc; 369 } 370 } 371 #else 372 RTTHREAD hThreadSelf = RTThreadSelf(); 373 #endif 374 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT_MULTI, true); 354 375 rc = pthread_cond_wait(&pThis->Cond, &pThis->Mutex); 376 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT_MULTI); 355 377 if (rc) 356 378 { … … 396 418 397 419 /* take mutex */ 398 #ifdef RT_OS_DARWIN399 420 int rc = pthread_mutex_lock(&pThis->Mutex); 400 #else401 int rc = pthread_mutex_timedlock(&pThis->Mutex, &ts);402 #endif403 421 if (rc) 404 422 { … … 425 443 } 426 444 445 /* we're done if the timeout is 0. */ 446 if (!cMillies) 447 { 448 ASMAtomicDecU32(&pThis->cWaiters); 449 rc = pthread_mutex_unlock(&pThis->Mutex); 450 return VERR_SEM_BUSY; 451 } 452 427 453 /* wait */ 454 #ifdef RTSEMEVENTMULTI_STRICT 455 RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt(); 456 if (pThis->fEverHadSignallers) 457 { 458 rc = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false, 459 RTTHREADSTATE_EVENT_MULTI, true); 460 if (RT_FAILURE(rc)) 461 { 462 ASMAtomicDecU32(&pThis->cWaiters); 463 pthread_mutex_unlock(&pThis->Mutex); 464 return rc; 465 } 466 } 467 #else 468 RTTHREAD hThreadSelf = RTThreadSelf(); 469 #endif 470 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT_MULTI, true); 428 471 rc = pthread_cond_timedwait(&pThis->Cond, &pThis->Mutex, &ts); 472 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT_MULTI); 429 473 if (rc && (rc != EINTR || !fAutoResume)) /* according to SuS this function shall not return EINTR, but linux man page says differently. */ 430 474 { … … 453 497 } 454 498 499 500 RTDECL(void) RTSemEventMultiSetSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread) 501 { 502 #ifdef RTSEMEVENTMULTI_STRICT 503 struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem; 504 AssertPtrReturnVoid(pThis); 505 uint32_t u32 = pThis->u32State; 506 AssertReturnVoid(u32 == EVENTMULTI_STATE_NOT_SIGNALED || u32 == EVENTMULTI_STATE_SIGNALED); 507 508 ASMAtomicWriteBool(&pThis->fEverHadSignallers, true); 509 RTLockValidatorRecSharedResetOwner(&pThis->Signallers, hThread, NULL); 510 #endif 511 } 512 513 514 RTDECL(void) RTSemEventMultiAddSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread) 515 { 516 #ifdef RTSEMEVENTMULTI_STRICT 517 struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem; 518 AssertPtrReturnVoid(pThis); 519 uint32_t u32 = pThis->u32State; 520 AssertReturnVoid(u32 == EVENTMULTI_STATE_NOT_SIGNALED || u32 == EVENTMULTI_STATE_SIGNALED); 521 522 ASMAtomicWriteBool(&pThis->fEverHadSignallers, true); 523 RTLockValidatorRecSharedAddOwner(&pThis->Signallers, hThread, NULL); 524 #endif 525 } 526 527 528 RTDECL(void) RTSemEventMultiRemoveSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread) 529 { 530 #ifdef RTSEMEVENTMULTI_STRICT 531 struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem; 532 AssertPtrReturnVoid(pThis); 533 uint32_t u32 = pThis->u32State; 534 AssertReturnVoid(u32 == EVENTMULTI_STATE_NOT_SIGNALED || u32 == EVENTMULTI_STATE_SIGNALED); 535 536 RTLockValidatorRecSharedRemoveOwner(&pThis->Signallers, hThread); 537 #endif 538 } 539
Note:
See TracChangeset
for help on using the changeset viewer.