| 768 | } |
| 769 | |
| 770 | void BufferPool::Client::WriteCompleteCallback(Page* page, const Status& write_status) { |
| 771 | #ifndef NDEBUG |
| 772 | if (debug_write_delay_ms_ > 0) SleepForMs(debug_write_delay_ms_); |
| 773 | #endif |
| 774 | { |
| 775 | unique_lock<mutex> cl(lock_); |
| 776 | DCHECK(in_flight_write_pages_.Contains(page)) << DebugStringLocked(); |
| 777 | // The status should always be propagated. |
| 778 | // TODO: if we add cancellation support to TmpFileMgr, consider cancellation path. |
| 779 | if (!write_status.ok()) write_status_.MergeStatus(write_status); |
| 780 | in_flight_write_pages_.Remove(page); |
| 781 | // Move to clean pages list even if an error was encountered - the buffer can be |
| 782 | // repurposed by other clients and 'write_status_' must be checked by this client |
| 783 | // before it can be re-pinned. |
| 784 | pool_->allocator_->AddCleanPage(cl, page); |
| 785 | WriteDirtyPagesAsync(); // Start another asynchronous write if needed. |
| 786 | |
| 787 | // Notify before releasing lock to avoid race with Page and Client destruction. |
| 788 | page->write_complete_cv_.NotifyAll(); |
| 789 | write_complete_cv_.NotifyAll(); |
| 790 | } |
| 791 | } |
| 792 | |
| 793 | void BufferPool::Client::WaitForWrite(unique_lock<mutex>* client_lock, Page* page) { |
| 794 | DCheckHoldsLock(*client_lock); |
nothing calls this directly
no test coverage detected