#pragma once
+#include <future>
+
#include <folly/Baton.h>
#include <folly/Executor.h>
#include <folly/io/async/EventBase.h>
VirtualEventBase(const VirtualEventBase&) = delete;
VirtualEventBase& operator=(const VirtualEventBase&) = delete;
- ~VirtualEventBase();
+ ~VirtualEventBase() override;
EventBase& getEventBase() {
return evb_;
*/
void runOnDestruction(EventBase::LoopCallback* callback);
- /**
- * @see EventBase::runInLoop
- */
- template <typename F>
- void runInLoop(F&& f, bool thisIteration = false) {
- evb_.runInLoop(std::forward<F>(f), thisIteration);
- }
-
/**
* VirtualEventBase destructor blocks until all tasks scheduled through its
* runInEventBaseThread are complete.
* KeepAlive handle can be released from EventBase loop only.
*/
KeepAlive getKeepAliveToken() override {
+ DCHECK(loopKeepAliveCount_ + loopKeepAliveCountAtomic_.load() > 0);
+
if (evb_.inRunningEventBaseThread()) {
++loopKeepAliveCount_;
} else {
protected:
void keepAliveRelease() override {
- DCHECK(getEventBase().inRunningEventBaseThread());
+ DCHECK(getEventBase().isInEventBaseThread());
if (loopKeepAliveCountAtomic_.load()) {
loopKeepAliveCount_ += loopKeepAliveCountAtomic_.exchange(0);
}
DCHECK(loopKeepAliveCount_ > 0);
if (--loopKeepAliveCount_ == 0) {
- loopKeepAliveBaton_.post();
+ destroyImpl();
}
}
private:
+ friend class EventBase;
+
+ ssize_t keepAliveCount() {
+ if (loopKeepAliveCountAtomic_.load()) {
+ loopKeepAliveCount_ += loopKeepAliveCountAtomic_.exchange(0);
+ }
+ return loopKeepAliveCount_;
+ }
+
+ std::future<void> destroy();
+ void destroyImpl();
+
using LoopCallbackList = EventBase::LoopCallback::List;
EventBase& evb_;
- ssize_t loopKeepAliveCount_{0};
+ ssize_t loopKeepAliveCount_{1};
std::atomic<ssize_t> loopKeepAliveCountAtomic_{0};
- folly::Baton<> loopKeepAliveBaton_;
- KeepAlive loopKeepAlive_;
+ std::promise<void> destroyPromise_;
+ std::future<void> destroyFuture_{destroyPromise_.get_future()};
+ KeepAlive loopKeepAlive_{makeKeepAlive()};
KeepAlive evbLoopKeepAlive_;