event_base_free(evb_);
}
+ while (!runAfterDrainCallbacks_.empty()) {
+ LoopCallback* callback = &runAfterDrainCallbacks_.front();
+ runAfterDrainCallbacks_.pop_front();
+ callback->runLoopCallback();
+ }
+
{
std::lock_guard<std::mutex> lock(localStorageMutex_);
for (auto storage : localStorageToDtor_) {
}
}
+void EventBase::runAfterDrain(Cob&& cob) {
+ auto callback = new FunctionLoopCallback<Cob>(std::move(cob));
+ std::lock_guard<std::mutex> lg(runAfterDrainCallbacksMutex_);
+ callback->cancelLoopCallback();
+ runAfterDrainCallbacks_.push_back(*callback);
+}
+
void EventBase::runOnDestruction(LoopCallback* callback) {
std::lock_guard<std::mutex> lg(onDestructionCallbacksMutex_);
callback->cancelLoopCallback();
*/
void runOnDestruction(LoopCallback* callback);
+ /**
+ * Adds the given callback to a queue of things run after the notification
+ * queue is drained before the destruction of current EventBase.
+ *
+ * Note: will be called from the thread that invoked EventBase destructor,
+ * after the final run of loop callbacks.
+ */
+ void runAfterDrain(Cob&& cob);
+
/**
* Adds a callback that will run immediately *before* the event loop.
* This is very similar to runInLoop(), but will not cause the loop to break:
LoopCallbackList loopCallbacks_;
LoopCallbackList runBeforeLoopCallbacks_;
LoopCallbackList onDestructionCallbacks_;
+ LoopCallbackList runAfterDrainCallbacks_;
// This will be null most of the time, but point to currentCallbacks
// if we are in the middle of running loop callbacks, such that
// allow runOnDestruction() to be called from any threads
std::mutex onDestructionCallbacksMutex_;
+ // allow runAfterDrain() to be called from any threads
+ std::mutex runAfterDrainCallbacksMutex_;
+
// see EventBaseLocal
friend class detail::EventBaseLocalBase;
template <typename T> friend class EventBaseLocal;