}
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
}
}
+void EventBase::runOnDestruction(LoopCallback* callback) {
+ DCHECK(isInEventBaseThread());
+ callback->cancelLoopCallback();
+ onDestructionCallbacks_.push_back(*callback);
+}
+
bool EventBase::runInEventBaseThread(void (*fn)(void*), void* arg) {
// Send the message.
// It will be received by the FunctionRunner in the EventBase's thread.
void runInLoop(Cob&& c, bool thisIteration = false);
+ /**
+ * Adds the given callback to a queue of things run before destruction
+ * of current EventBase.
+ *
+ * This allows users of EventBase that run in it, but don't control it,
+ * to be notified before EventBase gets destructed.
+ *
+ * Note: will be called from the thread that invoked EventBase destructor,
+ * before the final run of loop callbacks.
+ */
+ void runOnDestruction(LoopCallback* callback);
+
/**
* Run the specified function in the EventBase's thread.
*
CobTimeout::List pendingCobTimeouts_;
LoopCallbackList loopCallbacks_;
+ LoopCallbackList onDestructionCallbacks_;
// This will be null most of the time, but point to currentCallbacks
// if we are in the middle of running loop callbacks, such that