2 * Copyright 2015 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <folly/Singleton.h>
18 #include <folly/wangle/concurrent/IOExecutor.h>
19 #include <folly/wangle/concurrent/IOThreadPoolExecutor.h>
20 #include <folly/futures/InlineExecutor.h>
22 using namespace folly;
23 using namespace folly::wangle;
27 // lock protecting global CPU executor
28 struct CPUExecutorLock {};
29 Singleton<RWSpinLock, CPUExecutorLock> globalCPUExecutorLock;
30 // global CPU executor
31 Singleton<std::weak_ptr<Executor>> globalCPUExecutor;
32 // default global CPU executor is an InlineExecutor
33 Singleton<std::shared_ptr<InlineExecutor>> globalInlineExecutor(
35 return new std::shared_ptr<InlineExecutor>(
36 std::make_shared<InlineExecutor>());
39 // lock protecting global IO executor
40 struct IOExecutorLock {};
41 Singleton<RWSpinLock, IOExecutorLock> globalIOExecutorLock;
43 Singleton<std::weak_ptr<IOExecutor>> globalIOExecutor;
44 // default global IO executor is an IOThreadPoolExecutor
45 Singleton<std::shared_ptr<IOThreadPoolExecutor>> globalIOThreadPool(
47 return new std::shared_ptr<IOThreadPoolExecutor>(
48 std::make_shared<IOThreadPoolExecutor>(
49 sysconf(_SC_NPROCESSORS_ONLN),
50 std::make_shared<NamedThreadFactory>("GlobalIOThreadPool")));
55 namespace folly { namespace wangle {
57 template <class Exe, class DefaultExe, class LockTag>
58 std::shared_ptr<Exe> getExecutor(
59 Singleton<std::weak_ptr<Exe>>& sExecutor,
60 Singleton<std::shared_ptr<DefaultExe>>& sDefaultExecutor,
61 Singleton<RWSpinLock, LockTag>& sExecutorLock) {
62 std::shared_ptr<Exe> executor;
63 auto singleton = sExecutor.get();
64 auto lock = sExecutorLock.get();
67 RWSpinLock::ReadHolder guard(lock);
68 if ((executor = sExecutor->lock())) {
74 RWSpinLock::WriteHolder guard(lock);
75 executor = singleton->lock();
77 executor = *sDefaultExecutor.get();
78 *singleton = executor;
83 template <class Exe, class LockTag>
85 std::shared_ptr<Exe> executor,
86 Singleton<std::weak_ptr<Exe>>& sExecutor,
87 Singleton<RWSpinLock, LockTag>& sExecutorLock) {
88 RWSpinLock::WriteHolder guard(sExecutorLock.get());
89 *sExecutor.get() = std::move(executor);
92 std::shared_ptr<Executor> getCPUExecutor() {
96 globalCPUExecutorLock);
99 void setCPUExecutor(std::shared_ptr<Executor> executor) {
103 globalCPUExecutorLock);
106 std::shared_ptr<IOExecutor> getIOExecutor() {
110 globalIOExecutorLock);
113 void setIOExecutor(std::shared_ptr<IOExecutor> executor) {
117 globalIOExecutorLock);