void ThreadPoolTaskExecutor::wait(const CallbackHandle& cbHandle) { invariant(cbHandle.isValid()); auto cbState = checked_cast<CallbackState*>(getCallbackFromHandle(cbHandle)); if (cbState->isFinished.load()) { return; } stdx::unique_lock<stdx::mutex> lk(_mutex); if (!cbState->finishedCondition) { cbState->finishedCondition.emplace(); } while (!cbState->isFinished.load()) { cbState->finishedCondition->wait(lk); } }
void ThreadPoolTaskExecutor::cancel(const CallbackHandle& cbHandle) { invariant(cbHandle.isValid()); auto cbState = checked_cast<CallbackState*>(getCallbackFromHandle(cbHandle)); stdx::unique_lock<stdx::mutex> lk(_mutex); cbState->canceled.store(1); if (cbState->isNetworkOperation) { lk.unlock(); _net->cancelCommand(cbHandle); return; } if (cbState->readyDate != Date_t{}) { // This callback might still be in the sleeper queue; if it is, schedule it now // rather than when the alarm fires. auto iter = std::find_if(_sleepersQueue.begin(), _sleepersQueue.end(), [cbState](const std::shared_ptr<CallbackState>& other) { return cbState == other.get(); }); if (iter != _sleepersQueue.end()) { invariant(iter == cbState->iter); scheduleIntoPool_inlock(&_sleepersQueue, cbState->iter); } } }
void ThreadPoolTaskExecutor::wait(const CallbackHandle& cbHandle) { invariant(cbHandle.isValid()); auto cbState = checked_cast<CallbackState*>(getCallbackFromHandle(cbHandle)); waitForEvent(cbState->finishedEvent); }