| 456 | } |
| 457 | |
| 458 | void Stream::ClearGCBag() |
| 459 | { |
| 460 | GCBag objectsToBeDestroyed; |
| 461 | |
| 462 | GCBag &gcBag = GetGCBag(); |
| 463 | |
| 464 | std::unique_lock lk(m_gcMutex); |
| 465 | // Do as little as possible while mutex is locked to avoid |
| 466 | // deadlocks. |
| 467 | |
| 468 | // In the case here, instead of simply empting up the gc bag, |
| 469 | // which might trigger object destruction while the mutex is locked, |
| 470 | // we move its contents to a temporary local bag. |
| 471 | |
| 472 | // take of benefit of ADL if available |
| 473 | using std::swap; |
| 474 | swap(objectsToBeDestroyed, gcBag); |
| 475 | |
| 476 | // Now the original bag is left empty, but no objects were |
| 477 | // destroyed yet. |
| 478 | NVCV_ASSERT(gcBag.empty()); // post-condition (can't be guaranteed after unlock) |
| 479 | |
| 480 | lk.unlock(); |
| 481 | |
| 482 | // Let the local object bag go out of scope, the objects in it |
| 483 | // will be finally destroyed with the mutex unlocked. |
| 484 | } |
| 485 | |
| 486 | std::ostream &operator<<(std::ostream &out, const Stream &stream) |
| 487 | { |