void ReplicationExecutor::doOperationWithGlobalExclusiveLock( OperationContext* txn, const CallbackHandle& cbHandle) { boost::unique_lock<boost::mutex> lk(_mutex); if (_inShutdown) return; const WorkQueue::iterator iter = cbHandle._iter; const uint64_t generation = iter->generation; invariant(generation == cbHandle._generation); WorkItem work = *iter; iter->callback = CallbackFn(); _freeQueue.splice(_freeQueue.begin(), _exclusiveLockInProgressQueue, iter); lk.unlock(); { boost::lock_guard<boost::mutex> terribleLock(_terribleExLockSyncMutex); work.callback(CallbackData(this, cbHandle, (work.isCanceled ? Status(ErrorCodes::CallbackCanceled, "Callback canceled") : Status::OK()), txn)); } lk.lock(); signalEvent_inlock(work.finishedEvent); }
void ThreadPoolTaskExecutor::runCallback(std::shared_ptr<CallbackState> cbStateArg) { auto cbStatePtr = cbStateArg.get(); CallbackHandle cbHandle; setCallbackForHandle(&cbHandle, std::move(cbStateArg)); CallbackArgs args(this, std::move(cbHandle), cbStatePtr->canceled.load() ? Status({ErrorCodes::CallbackCanceled, "Callback canceled"}) : Status::OK()); cbStatePtr->callback(std::move(args)); stdx::lock_guard<stdx::mutex> lk(_mutex); if (cbStatePtr->finishedEvent.isValid()) { signalEvent_inlock(cbStatePtr->finishedEvent); } _poolInProgressQueue.erase(cbStatePtr->iter); }
void ThreadPoolTaskExecutor::join() { _pool->join(); stdx::unique_lock<stdx::mutex> lk(_mutex); while (!_unsignaledEvents.empty()) { auto eventState = _unsignaledEvents.front(); invariant(eventState->waiters.empty()); EventHandle event; setEventForHandle(&event, std::move(eventState)); signalEvent_inlock(event); } lk.unlock(); _net->shutdown(); lk.lock(); invariant(_poolInProgressQueue.empty()); invariant(_networkInProgressQueue.empty()); invariant(_sleepersQueue.empty()); invariant(_unsignaledEvents.empty()); }
void ReplicationExecutor::finishShutdown() { _dblockWorkers.join(); boost::unique_lock<boost::mutex> lk(_mutex); invariant(_inShutdown); invariant(_exclusiveLockInProgressQueue.empty()); invariant(_readyQueue.empty()); invariant(_sleepersQueue.empty()); while (!_unsignaledEvents.empty()) { EventList::iterator event = _unsignaledEvents.begin(); invariant(event->waiters.empty()); signalEvent_inlock(EventHandle(event, ++_nextId)); } while (_totalEventWaiters > 0) _noMoreWaitingThreads.wait(lk); invariant(_exclusiveLockInProgressQueue.empty()); invariant(_readyQueue.empty()); invariant(_sleepersQueue.empty()); invariant(_unsignaledEvents.empty()); }
void ReplicationExecutor::signalEvent(const EventHandle& event) { boost::lock_guard<boost::mutex> lk(_mutex); signalEvent_inlock(event); }
void ThreadPoolTaskExecutor::signalEvent(const EventHandle& event) { stdx::lock_guard<stdx::mutex> lk(_mutex); signalEvent_inlock(event); }