Changeset 25513 in vbox for trunk/src/VBox/Runtime/generic
- Timestamp:
- Dec 20, 2009 12:56:55 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 56186
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/generic/semrw-generic.cpp
r25438 r25513 79 79 /** The handle of the event object on which the waiting writers block. (automatic reset). */ 80 80 RTSEMEVENT WriteEvent; 81 /** Need to reset ReadEvent. */ 82 bool fNeedResetReadEvent; 81 83 }; 82 84 83 84 /**85 * Validate a read-write semaphore handle passed to one of the interface.86 *87 * @returns true if valid.88 * @returns false if invalid.89 * @param pThis Pointer to the read-write semaphore to validate.90 */91 inline bool rtsemRWValid(struct RTSEMRWINTERNAL *pThis)92 {93 if (!VALID_PTR(pThis))94 return false;95 96 if (pThis->u32Magic != RTSEMRW_MAGIC)97 return false;98 return true;99 }100 85 101 86 … … 128 113 if (RT_SUCCESS(rc)) 129 114 { 130 pThis->u32Padding = 0xa5a55a5a; 131 pThis->cReads = 0; 132 pThis->cWrites = 0; 133 pThis->cWriterReads = 0; 134 pThis->cWritesWaiting = 0; 135 pThis->Writer = NIL_RTTHREAD; 136 pThis->u32Magic = RTSEMRW_MAGIC; 115 pThis->u32Padding = UINT32_C(0xa5a55a5a); 116 pThis->cReads = 0; 117 pThis->cWrites = 0; 118 pThis->cWriterReads = 0; 119 pThis->cWritesWaiting = 0; 120 pThis->Writer = NIL_RTTHREAD; 121 pThis->fNeedResetReadEvent = true; 122 pThis->u32Magic = RTSEMRW_MAGIC; 137 123 *pRWSem = pThis; 138 124 return VINF_SUCCESS; … … 157 143 { 158 144 struct RTSEMRWINTERNAL *pThis = RWSem; 159 /* 160 * Validate handle.161 * /162 if (!rtsemRWValid(pThis))163 {164 AssertMsgFailed(("Invalid handle %p!\n", RWSem));165 return VERR_INVALID_HANDLE;166 }145 146 /* 147 * Validate handle. 148 */ 149 if (pThis == NIL_RTSEMRW) 150 return VINF_SUCCESS; 151 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 152 AssertReturn(pThis->u32Magic == RTSEMRW_MAGIC, VERR_INVALID_HANDLE); 167 153 168 154 /* … … 177 163 * Make it invalid and unusable. 178 164 */ 179 pThis->u32Magic = ~RTSEMRW_MAGIC;165 ASMAtomicWriteU32(&pThis->u32Magic, ~RTSEMRW_MAGIC); 180 166 pThis->cReads = ~0; 181 167 … … 184 170 */ 185 171 rc = RTSemEventMultiDestroy(pThis->ReadEvent); 186 AssertMsgRC(rc, ("RTSemEventMultiDestroy failed! rc=% d\n", rc));172 AssertMsgRC(rc, ("RTSemEventMultiDestroy failed! rc=%Rrc\n", rc)); 187 173 pThis->ReadEvent = NIL_RTSEMEVENTMULTI; 188 174 189 175 rc = RTSemEventDestroy(pThis->WriteEvent); 190 AssertMsgRC(rc, ("RTSemEventDestroy failed! rc=% d\n", rc));176 AssertMsgRC(rc, ("RTSemEventDestroy failed! rc=%Rrc\n", rc)); 191 177 pThis->WriteEvent = NIL_RTSEMEVENT; 192 178 193 179 RTCritSectLeave(&pThis->CritSect); 194 180 rc = RTCritSectDelete(&pThis->CritSect); 195 AssertMsgRC(rc, ("RTCritSectDelete failed! rc=% d\n", rc));181 AssertMsgRC(rc, ("RTCritSectDelete failed! rc=%Rrc\n", rc)); 196 182 197 183 RTMemFree(pThis); … … 206 192 else 207 193 { 208 AssertMsgRC(rc, ("RTCritSectTryEnter failed! rc=% d\n", rc));194 AssertMsgRC(rc, ("RTCritSectTryEnter failed! rc=%Rrc\n", rc)); 209 195 rc = VERR_SEM_BUSY; 210 196 } … … 218 204 { 219 205 struct RTSEMRWINTERNAL *pThis = RWSem; 220 /* 221 * Validate handle. 222 */ 223 if (!rtsemRWValid(pThis)) 224 { 225 AssertMsgFailed(("Invalid handle %p!\n", RWSem)); 226 return VERR_INVALID_HANDLE; 227 } 206 207 /* 208 * Validate handle. 209 */ 210 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 211 AssertReturn(pThis->u32Magic == RTSEMRW_MAGIC, VERR_INVALID_HANDLE); 228 212 229 213 RTTHREAD Self = (RTTHREAD)RTThreadNativeSelf(); … … 239 223 if (RT_FAILURE(rc)) 240 224 { 241 AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=% d\n", RWSem, rc));225 AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=%Rrc\n", RWSem, rc)); 242 226 return rc; 243 227 } … … 250 234 * that will break/deadlock reader recursion. 251 235 */ 252 if (!pThis->cWrites) 236 if (!pThis->cWrites 237 /** @todo && ( pThis->cReads 238 * || !pThis->cWritesWaiting) ?? - making sure not to race waiting 239 * writers. */ 240 ) 253 241 { 254 242 pThis->cReads++; … … 257 245 return VINF_SUCCESS; 258 246 } 259 else if (pThis->Writer == Self) 247 248 if (pThis->Writer == Self) 260 249 { 261 250 pThis->cWriterReads++; … … 283 272 if (RT_FAILURE(rc) && rc != VERR_TIMEOUT) 284 273 { 285 AssertMsgRC(rc, ("RTSemEventMultiWait failed on rwsem %p, rc=% d\n", RWSem, rc));274 AssertMsgRC(rc, ("RTSemEventMultiWait failed on rwsem %p, rc=%Rrc\n", RWSem, rc)); 286 275 break; 287 276 } … … 299 288 if (RT_FAILURE(rc)) 300 289 { 301 AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=% d\n", RWSem, rc));290 AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=%Rrc\n", RWSem, rc)); 302 291 break; 303 292 } … … 319 308 { 320 309 struct RTSEMRWINTERNAL *pThis = RWSem; 321 /* 322 * Validate handle. 323 */ 324 if (!rtsemRWValid(pThis)) 325 { 326 AssertMsgFailed(("Invalid handle %p!\n", RWSem)); 327 return VERR_INVALID_HANDLE; 328 } 310 311 /* 312 * Validate handle. 313 */ 314 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 315 AssertReturn(pThis->u32Magic == RTSEMRW_MAGIC, VERR_INVALID_HANDLE); 329 316 330 317 RTTHREAD Self = (RTTHREAD)RTThreadNativeSelf(); … … 350 337 { 351 338 rc = RTSemEventSignal(pThis->WriteEvent); 352 AssertMsgRC(rc, ("Failed to signal writers on rwsem %p, rc=% d\n", RWSem, rc));339 AssertMsgRC(rc, ("Failed to signal writers on rwsem %p, rc=%Rrc\n", RWSem, rc)); 353 340 } 354 341 } … … 358 345 } 359 346 else 360 AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=% d\n", RWSem, rc));347 AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=%Rrc\n", RWSem, rc)); 361 348 362 349 return rc; … … 368 355 { 369 356 struct RTSEMRWINTERNAL *pThis = RWSem; 370 /* 371 * Validate handle. 372 */ 373 if (!rtsemRWValid(pThis)) 374 { 375 AssertMsgFailed(("Invalid handle %p!\n", RWSem)); 376 return VERR_INVALID_HANDLE; 377 } 357 358 /* 359 * Validate handle. 360 */ 361 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 362 AssertReturn(pThis->u32Magic == RTSEMRW_MAGIC, VERR_INVALID_HANDLE); 378 363 379 364 RTTHREAD Self = (RTTHREAD)RTThreadNativeSelf(); 380 365 unsigned cMilliesInitial = cMillies; 381 366 uint64_t tsStart = 0; 382 if (cMillies != RT_INDEFINITE_WAIT )367 if (cMillies != RT_INDEFINITE_WAIT && cMillies != 0) 383 368 tsStart = RTTimeNanoTS(); 384 369 … … 389 374 if (RT_FAILURE(rc)) 390 375 { 391 AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=% d\n", RWSem, rc));376 AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=%Rrc\n", RWSem, rc)); 392 377 return rc; 393 378 } … … 406 391 { 407 392 /* 408 * Reset the reader event semaphore. For write recursion this 409 * is redundant, but does not hurt. 393 * Reset the reader event semaphore if necessary. 410 394 */ 411 rc = RTSemEventMultiReset(pThis->ReadEvent); 412 AssertMsgRC(rc, ("Failed to reset readers, rwsem %p, rc=%d.\n", RWSem, rc)); 395 if (pThis->fNeedResetReadEvent) 396 { 397 pThis->fNeedResetReadEvent = false; 398 rc = RTSemEventMultiReset(pThis->ReadEvent); 399 AssertMsgRC(rc, ("Failed to reset readers, rwsem %p, rc=%Rrc.\n", RWSem, rc)); 400 } 413 401 414 402 pThis->cWrites++; … … 425 413 * Wait till it's ready for writing. 426 414 */ 427 if (cMillies != RT_INDEFINITE_WAIT )415 if (cMillies != RT_INDEFINITE_WAIT && cMillies != 0) 428 416 { 429 417 int64_t tsDelta = RTTimeNanoTS() - tsStart; … … 436 424 } 437 425 rc = RTSemEventWait(pThis->WriteEvent, cMillies); 438 if (RT_ FAILURE(rc) && rc != VERR_TIMEOUT)439 { 440 AssertMsgRC(rc, ("RTSemEventWait failed on rwsem %p, rc=% d\n", RWSem, rc));426 if (RT_UNLIKELY(RT_FAILURE_NP(rc) && rc != VERR_TIMEOUT)) 427 { 428 AssertMsgRC(rc, ("RTSemEventWait failed on rwsem %p, rc=%Rrc\n", RWSem, rc)); 441 429 break; 442 430 } 443 431 444 if ( pThis->u32Magic != RTSEMRW_MAGIC)432 if (RT_UNLIKELY(pThis->u32Magic != RTSEMRW_MAGIC)) 445 433 { 446 434 rc = VERR_SEM_DESTROYED; … … 454 442 if (RT_FAILURE(rc)) 455 443 { 456 AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=% d\n", RWSem, rc));444 AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=%Rrc\n", RWSem, rc)); 457 445 break; 458 446 } … … 485 473 { 486 474 struct RTSEMRWINTERNAL *pThis = RWSem; 487 /* 488 * Validate handle. 489 */ 490 if (!rtsemRWValid(pThis)) 491 { 492 AssertMsgFailed(("Invalid handle %p!\n", RWSem)); 493 return VERR_INVALID_HANDLE; 494 } 475 476 /* 477 * Validate handle. 478 */ 479 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 480 AssertReturn(pThis->u32Magic == RTSEMRW_MAGIC, VERR_INVALID_HANDLE); 495 481 496 482 RTTHREAD Self = (RTTHREAD)RTThreadNativeSelf(); … … 502 488 if (RT_FAILURE(rc)) 503 489 { 504 AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=% d\n", RWSem, rc));490 AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=%Rrc\n", RWSem, rc)); 505 491 return rc; 506 492 } … … 530 516 { 531 517 rc = RTSemEventMultiSignal(pThis->ReadEvent); 532 AssertMsgRC(rc, ("RTSemEventMultiSignal failed for rwsem %p, rc=%d.\n", RWSem, rc)); 518 AssertMsgRC(rc, ("RTSemEventMultiSignal failed for rwsem %p, rc=%Rrc.\n", RWSem, rc)); 519 pThis->fNeedResetReadEvent = true; 533 520 } 534 521 else 535 522 { 536 523 rc = RTSemEventSignal(pThis->WriteEvent); 537 AssertMsgRC(rc, ("Failed to signal writers on rwsem %p, rc=% d\n", RWSem, rc));524 AssertMsgRC(rc, ("Failed to signal writers on rwsem %p, rc=%Rrc\n", RWSem, rc)); 538 525 } 539 526 RTCritSectLeave(&pThis->CritSect); … … 547 534 { 548 535 struct RTSEMRWINTERNAL *pThis = RWSem; 549 /* 550 * Validate handle. 551 */ 552 if (!rtsemRWValid(pThis)) 553 { 554 AssertMsgFailed(("Invalid handle %p!\n", RWSem)); 555 return false; 556 } 536 537 /* 538 * Validate handle. 539 */ 540 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 541 AssertReturn(pThis->u32Magic == RTSEMRW_MAGIC, VERR_INVALID_HANDLE); 557 542 558 543 /* … … 570 555 { 571 556 struct RTSEMRWINTERNAL *pThis = RWSem; 572 /* 573 * Validate handle. 574 */ 575 if (!rtsemRWValid(pThis)) 576 { 577 AssertMsgFailed(("Invalid handle %p!\n", RWSem)); 578 return 0; 579 } 557 558 /* 559 * Validate handle. 560 */ 561 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 562 AssertReturn(pThis->u32Magic == RTSEMRW_MAGIC, VERR_INVALID_HANDLE); 580 563 581 564 /* … … 590 573 { 591 574 struct RTSEMRWINTERNAL *pThis = RWSem; 592 /* 593 * Validate handle. 594 */ 595 if (!rtsemRWValid(pThis)) 596 { 597 AssertMsgFailed(("Invalid handle %p!\n", RWSem)); 598 return 0; 599 } 575 576 /* 577 * Validate handle. 578 */ 579 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 580 AssertReturn(pThis->u32Magic == RTSEMRW_MAGIC, VERR_INVALID_HANDLE); 600 581 601 582 /*
Note:
See TracChangeset
for help on using the changeset viewer.