bool OplogBufferCollection::peek(OperationContext* txn, Value* value) { stdx::lock_guard<stdx::mutex> lk(_mutex); if (_count == 0) { return false; } return _peekOneSide_inlock(txn, value, true); }
bool OplogBufferCollection::blockingPeek(OperationContext* txn, Value* value, Seconds waitDuration) { stdx::unique_lock<stdx::mutex> lk(_mutex); if (!_cvNoLongerEmpty.wait_for( lk, waitDuration.toSystemDuration(), [&]() { return _count != 0; })) { return false; } return _peekOneSide_inlock(txn, value, true); }
boost::optional<OplogBuffer::Value> OplogBufferCollection::lastObjectPushed( OperationContext* txn) const { stdx::lock_guard<stdx::mutex> lk(_mutex); if (_count == 0) { return boost::none; } Value value; bool res = _peekOneSide_inlock(txn, &value, false); if (!res) { return boost::none; } return value; }
bool OplogBufferCollection::_pop_inlock(OperationContext* txn, Value* value) { // If there is a sentinel, and it was pushed right after the last BSONObj to be popped was // pushed, then we pop off a sentinel instead and decrease the count by 1. if (!_sentinels.empty() && (_lastPoppedTimestamp == _sentinels.front())) { _sentinels.pop(); _count--; *value = BSONObj(); return true; } if (!_peekOneSide_inlock(txn, value, true)) { return false; } _lastPoppedTimestamp = (*value)["ts"].timestamp(); invariant(_count > 0); invariant(_size >= std::size_t(value->objsize())); _count--; _size -= value->objsize(); return true; }