/* * Copyright 2017-present Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include using namespace folly; namespace { template class GlobalExecutor { public: explicit GlobalExecutor( Function()> constructDefault) : constructDefault_(std::move(constructDefault)) {} std::shared_ptr get() { { SharedMutex::ReadHolder guard(mutex_); if (auto executor = executor_.lock()) { return executor; // Fast path. } } SharedMutex::WriteHolder guard(mutex_); if (auto executor = executor_.lock()) { return executor; } if (!defaultExecutor_) { defaultExecutor_ = constructDefault_(); } return defaultExecutor_; } void set(std::weak_ptr executor) { SharedMutex::WriteHolder guard(mutex_); executor_.swap(executor); } private: SharedMutex mutex_; std::weak_ptr executor_; std::shared_ptr defaultExecutor_; Function()> constructDefault_; }; Singleton> gGlobalCPUExecutor([] { return new GlobalExecutor( // Default global CPU executor is an InlineExecutor. [] { return std::make_unique(); }); }); Singleton> gGlobalIOExecutor([] { return new GlobalExecutor( // Default global IO executor is an IOThreadPoolExecutor. [] { return std::make_unique( std::thread::hardware_concurrency(), std::make_shared("GlobalIOThreadPool")); }); }); } // namespace namespace folly { std::shared_ptr getCPUExecutor() { if (auto singleton = gGlobalCPUExecutor.try_get()) { return singleton->get(); } return nullptr; } void setCPUExecutor(std::weak_ptr executor) { if (auto singleton = gGlobalCPUExecutor.try_get()) { singleton->set(std::move(executor)); } } std::shared_ptr getIOExecutor() { if (auto singleton = gGlobalIOExecutor.try_get()) { return singleton->get(); } return nullptr; } void setIOExecutor(std::weak_ptr executor) { if (auto singleton = gGlobalIOExecutor.try_get()) { singleton->set(std::move(executor)); } } EventBase* getEventBase() { return getIOExecutor()->getEventBase(); } } // namespace folly