ButlerThread::CallbackHandle ButlerThread::AddCallback(Callback const & callback) { unique_lock lock(callbackMutex_); auto it = callbacks_.insert(callbacks_.end(), callback); return CallbackHandle(*this, it); }
std::pair<ReplicationExecutor::WorkItem, ReplicationExecutor::CallbackHandle> ReplicationExecutor::getWork() { boost::unique_lock<boost::mutex> lk(_mutex); while (true) { const Date_t now = _networkInterface->now(); Date_t nextWakeupDate = scheduleReadySleepers_inlock(now); if (!_readyQueue.empty()) { break; } else if (_inShutdown) { return std::make_pair(WorkItem(), CallbackHandle()); } lk.unlock(); if (nextWakeupDate == Date_t(~0ULL)) { _networkInterface->waitForWork(); } else { _networkInterface->waitForWorkUntil(nextWakeupDate); } lk.lock(); } const CallbackHandle cbHandle(_readyQueue.begin()); const WorkItem work = *cbHandle._iter; _readyQueue.begin()->callback = CallbackFn(); _freeQueue.splice(_freeQueue.begin(), _readyQueue, _readyQueue.begin()); return std::make_pair(work, cbHandle); }
CallbackHandle GraphObject::registerCallback(const string& attr, Attribute::Callback cb) { auto attribute = _attribFunctions.find(attr); if (attribute == _attribFunctions.end()) return CallbackHandle(); return attribute->second.registerCallback(shared_from_this(), cb); }
StatusWith<ReplicationExecutor::CallbackHandle> ReplicationExecutor::enqueueWork_inlock( WorkQueue* queue, const CallbackFn& callback) { invariant(callback); StatusWith<EventHandle> event = makeEvent_inlock(); if (!event.isOK()) return StatusWith<CallbackHandle>(event.getStatus()); if (_freeQueue.empty()) _freeQueue.push_front(WorkItem()); const WorkQueue::iterator iter = _freeQueue.begin(); iter->generation++; iter->callback = callback; iter->finishedEvent = event.getValue(); iter->readyDate = Date_t(); iter->isCanceled = false; queue->splice(queue->end(), _freeQueue, iter); return StatusWith<CallbackHandle>(CallbackHandle(iter)); }