19 #include <unordered_map> 29 template <
typename EventBaseT>
30 class EventBaseOnDestructionCallback :
public EventBase::LoopCallback {
32 explicit EventBaseOnDestructionCallback(EventBaseT& evb) :
evb_(evb) {}
33 void runLoopCallback()
noexcept override;
39 template <typename EventBaseT>
42 static FiberManager&
get(EventBaseT& evb,
const FiberManager::Options& opts) {
43 return instance().getImpl(evb, opts);
46 static std::unique_ptr<FiberManager> erase(EventBaseT& evb) {
47 return instance().eraseImpl(evb);
55 static GlobalCache& instance() {
56 static auto ret =
new GlobalCache();
60 FiberManager& getImpl(EventBaseT& evb,
const FiberManager::Options& opts) {
61 std::lock_guard<std::mutex> lg(
mutex_);
63 auto& fmPtrRef =
map_[&evb];
66 auto loopController = std::make_unique<EventBaseLoopController>();
67 loopController->attachEventBase(evb);
68 evb.runOnDestruction(
new EventBaseOnDestructionCallback<EventBaseT>(evb));
71 std::make_unique<FiberManager>(
std::move(loopController), opts);
77 std::unique_ptr<FiberManager> eraseImpl(EventBaseT& evb) {
78 std::lock_guard<std::mutex> lg(
mutex_);
80 DCHECK_EQ(
map_.count(&evb), 1u);
88 std::unordered_map<EventBaseT*, std::unique_ptr<FiberManager>>
map_;
91 constexpr
size_t kEraseListMaxSize = 64;
93 template <
typename EventBaseT>
94 class ThreadLocalCache {
96 static FiberManager&
get(EventBaseT& evb,
const FiberManager::Options& opts) {
97 return instance()->getImpl(evb, opts);
100 static void erase(EventBaseT& evb) {
101 for (
auto& localInstance : instance().accessAllThreads()) {
102 localInstance.eraseInfo_.withWLock([&](
auto&
info) {
103 if (
info.eraseList.size() >= kEraseListMaxSize) {
104 info.eraseAll =
true;
106 info.eraseList.push_back(&evb);
108 localInstance.eraseRequested_ =
true;
114 ThreadLocalCache() {}
116 struct ThreadLocalCacheTag {};
117 using ThreadThreadLocalCache =
118 ThreadLocal<ThreadLocalCache, ThreadLocalCacheTag>;
122 static ThreadThreadLocalCache& instance() {
124 new ThreadThreadLocalCache([]() {
return new ThreadLocalCache(); });
128 FiberManager& getImpl(EventBaseT& evb,
const FiberManager::Options& opts) {
131 auto& fmPtrRef =
map_[&evb];
136 DCHECK(fmPtrRef !=
nullptr);
150 for (auto evbPtr : info.eraseList) {
155 info.eraseList.clear();
156 info.eraseAll =
false;
161 std::unordered_map<EventBaseT*, FiberManager*>
map_;
172 template <
typename EventBaseT>
173 void EventBaseOnDestructionCallback<EventBaseT>::runLoopCallback()
noexcept {
174 auto fm = GlobalCache<EventBaseT>::erase(
evb_);
175 DCHECK(fm.get() !=
nullptr);
176 ThreadLocalCache<EventBaseT>::erase(
evb_);
constexpr detail::Map< Move > move
folly::Synchronized< EraseInfo > eraseInfo_
—— Concurrent Priority Queue Implementation ——
requires E e noexcept(noexcept(s.error(std::move(e))))
Single-threaded task execution engine.
std::vector< EventBaseT * > eraseList
std::atomic< bool > eraseRequested_
std::unordered_map< EventBaseT *, std::unique_ptr< FiberManager > > map_
PUSHMI_INLINE_VAR constexpr detail::get_fn< T > get
FiberManager & getFiberManager(EventBase &evb, const FiberManager::Options &opts)