bool EventBase::runLoopCallbacks(bool setContext) { if (!loopCallbacks_.empty()) { bumpHandlingTime(); // Swap the loopCallbacks_ list with a temporary list on our stack. // This way we will only run callbacks scheduled at the time // runLoopCallbacks() was invoked. // // If any of these callbacks in turn call runInLoop() to schedule more // callbacks, those new callbacks won't be run until the next iteration // around the event loop. This prevents runInLoop() callbacks from being // able to start file descriptor and timeout based events. LoopCallbackList currentCallbacks; currentCallbacks.swap(loopCallbacks_); runOnceCallbacks_ = ¤tCallbacks; while (!currentCallbacks.empty()) { LoopCallback* callback = ¤tCallbacks.front(); currentCallbacks.pop_front(); if (setContext) { RequestContext::setContext(callback->context_); } callback->runLoopCallback(); } runOnceCallbacks_ = nullptr; return true; } return false; }
void fileAdded(File const &file, FileIndex const &) { GameStateFolder const &saveFolder = file.as<GameStateFolder>(); if (shouldAddFolder(saveFolder)) { mainCall.enqueue([this, &saveFolder] () { // Needs to be added. self().append(new SaveItem(saveFolder)); }); } }
void fileRemoved(File const &, FileIndex const &) { // Remove obsolete entries. mainCall.enqueue([this] () { for (ui::Data::Pos idx = self().size() - 1; idx < self().size(); --idx) { if (!self().at(idx).isValid()) { self().remove(idx); } } }); }
EventBase::~EventBase() { // Call all destruction callbacks, before we start cleaning up our state. while (!onDestructionCallbacks_.empty()) { LoopCallback* callback = &onDestructionCallbacks_.front(); onDestructionCallbacks_.pop_front(); callback->runLoopCallback(); } // Delete any unfired CobTimeout objects, so that we don't leak memory // (Note that we don't fire them. The caller is responsible for cleaning up // its own data structures if it destroys the EventBase with unfired events // remaining.) while (!pendingCobTimeouts_.empty()) { CobTimeout* timeout = &pendingCobTimeouts_.front(); delete timeout; } (void) runLoopCallbacks(false); // Stop consumer before deleting NotificationQueue fnRunner_->stopConsuming(); event_base_free(evb_); VLOG(5) << "EventBase(): Destroyed."; }