/*
- * Copyright 2016 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
namespace {
+template <typename EventBaseT>
class EventBaseOnDestructionCallback : public EventBase::LoopCallback {
public:
- explicit EventBaseOnDestructionCallback(EventBase& evb) : evb_(evb) {}
+ explicit EventBaseOnDestructionCallback(EventBaseT& evb) : evb_(evb) {}
void runLoopCallback() noexcept override;
private:
- EventBase& evb_;
+ EventBaseT& evb_;
};
+template <typename EventBaseT>
class GlobalCache {
public:
- static FiberManager& get(EventBase& evb, const FiberManager::Options& opts) {
+ static FiberManager& get(EventBaseT& evb, const FiberManager::Options& opts) {
return instance().getImpl(evb, opts);
}
- static std::unique_ptr<FiberManager> erase(EventBase& evb) {
+ static std::unique_ptr<FiberManager> erase(EventBaseT& evb) {
return instance().eraseImpl(evb);
}
return *ret;
}
- FiberManager& getImpl(EventBase& evb, const FiberManager::Options& opts) {
+ FiberManager& getImpl(EventBaseT& evb, const FiberManager::Options& opts) {
std::lock_guard<std::mutex> lg(mutex_);
auto& fmPtrRef = map_[&evb];
if (!fmPtrRef) {
- auto loopController = make_unique<EventBaseLoopController>();
+ auto loopController = std::make_unique<EventBaseLoopController>();
loopController->attachEventBase(evb);
- evb.runOnDestruction(new EventBaseOnDestructionCallback(evb));
+ evb.runOnDestruction(new EventBaseOnDestructionCallback<EventBaseT>(evb));
- fmPtrRef = make_unique<FiberManager>(std::move(loopController), opts);
+ fmPtrRef =
+ std::make_unique<FiberManager>(std::move(loopController), opts);
}
return *fmPtrRef;
}
- std::unique_ptr<FiberManager> eraseImpl(EventBase& evb) {
+ std::unique_ptr<FiberManager> eraseImpl(EventBaseT& evb) {
std::lock_guard<std::mutex> lg(mutex_);
- DCHECK_EQ(1, map_.count(&evb));
+ DCHECK_EQ(map_.count(&evb), 1u);
auto ret = std::move(map_[&evb]);
map_.erase(&evb);
}
std::mutex mutex_;
- std::unordered_map<EventBase*, std::unique_ptr<FiberManager>> map_;
+ std::unordered_map<EventBaseT*, std::unique_ptr<FiberManager>> map_;
};
constexpr size_t kEraseListMaxSize = 64;
+template <typename EventBaseT>
class ThreadLocalCache {
public:
- static FiberManager& get(EventBase& evb, const FiberManager::Options& opts) {
+ static FiberManager& get(EventBaseT& evb, const FiberManager::Options& opts) {
return instance()->getImpl(evb, opts);
}
- static void erase(EventBase& evb) {
+ static void erase(EventBaseT& evb) {
for (auto& localInstance : instance().accessAllThreads()) {
SYNCHRONIZED(info, localInstance.eraseInfo_) {
if (info.eraseList.size() >= kEraseListMaxSize) {
return *ret;
}
- FiberManager& getImpl(EventBase& evb, const FiberManager::Options& opts) {
+ FiberManager& getImpl(EventBaseT& evb, const FiberManager::Options& opts) {
eraseImpl();
auto& fmPtrRef = map_[&evb];
if (!fmPtrRef) {
- fmPtrRef = &GlobalCache::get(evb, opts);
+ fmPtrRef = &GlobalCache<EventBaseT>::get(evb, opts);
}
DCHECK(fmPtrRef != nullptr);
}
}
- std::unordered_map<EventBase*, FiberManager*> map_;
+ std::unordered_map<EventBaseT*, FiberManager*> map_;
std::atomic<bool> eraseRequested_{false};
struct EraseInfo {
bool eraseAll{false};
- std::vector<EventBase*> eraseList;
+ std::vector<EventBaseT*> eraseList;
};
folly::Synchronized<EraseInfo> eraseInfo_;
};
-void EventBaseOnDestructionCallback::runLoopCallback() noexcept {
- auto fm = GlobalCache::erase(evb_);
+template <typename EventBaseT>
+void EventBaseOnDestructionCallback<EventBaseT>::runLoopCallback() noexcept {
+ auto fm = GlobalCache<EventBaseT>::erase(evb_);
DCHECK(fm.get() != nullptr);
- ThreadLocalCache::erase(evb_);
+ ThreadLocalCache<EventBaseT>::erase(evb_);
delete this;
}
FiberManager& getFiberManager(
EventBase& evb,
const FiberManager::Options& opts) {
- return ThreadLocalCache::get(evb, opts);
+ return ThreadLocalCache<EventBase>::get(evb, opts);
+}
+
+FiberManager& getFiberManager(
+ VirtualEventBase& evb,
+ const FiberManager::Options& opts) {
+ return ThreadLocalCache<VirtualEventBase>::get(evb, opts);
}
}
}