1 | /* |
2 | * Copyright 2018-present Facebook, Inc. |
3 | * |
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 |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
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. |
15 | */ |
16 | |
17 | #pragma once |
18 | |
19 | #include <folly/DefaultKeepAliveExecutor.h> |
20 | |
21 | namespace folly { |
22 | |
23 | /** |
24 | * VirtualExecutor implements a light-weight view onto existing Executor. |
25 | * |
26 | * Multiple VirtualExecutors can be backed by a single Executor. |
27 | * |
28 | * VirtualExecutor's destructor blocks until all tasks scheduled through it are |
29 | * complete. Executor's destructor also blocks until all VirtualExecutors |
30 | * backed by it are released. |
31 | */ |
32 | class VirtualExecutor : public DefaultKeepAliveExecutor { |
33 | auto wrapFunc(Func f) { |
34 | class FuncAndKeepAlive { |
35 | public: |
36 | FuncAndKeepAlive(Func&& f, VirtualExecutor* executor) |
37 | : keepAlive_(getKeepAliveToken(executor)), f_(std::move(f)) {} |
38 | |
39 | void operator()() { |
40 | f_(); |
41 | } |
42 | |
43 | private: |
44 | Executor::KeepAlive<VirtualExecutor> keepAlive_; |
45 | Func f_; |
46 | }; |
47 | |
48 | return FuncAndKeepAlive(std::move(f), this); |
49 | } |
50 | |
51 | public: |
52 | explicit VirtualExecutor(KeepAlive<> executor) |
53 | : executor_(std::move(executor)) { |
54 | assert(!isKeepAliveDummy(executor_)); |
55 | } |
56 | |
57 | explicit VirtualExecutor(Executor* executor) |
58 | : VirtualExecutor(getKeepAliveToken(executor)) {} |
59 | |
60 | explicit VirtualExecutor(Executor& executor) |
61 | : VirtualExecutor(getKeepAliveToken(executor)) {} |
62 | |
63 | VirtualExecutor(const VirtualExecutor&) = delete; |
64 | VirtualExecutor& operator=(const VirtualExecutor&) = delete; |
65 | |
66 | uint8_t getNumPriorities() const override { |
67 | return executor_->getNumPriorities(); |
68 | } |
69 | |
70 | void add(Func f) override { |
71 | executor_->add(wrapFunc(std::move(f))); |
72 | } |
73 | |
74 | void addWithPriority(Func f, int8_t priority) override { |
75 | executor_->addWithPriority(wrapFunc(std::move(f)), priority); |
76 | } |
77 | |
78 | ~VirtualExecutor() override { |
79 | joinKeepAlive(); |
80 | } |
81 | |
82 | private: |
83 | const KeepAlive<> executor_; |
84 | }; |
85 | |
86 | } // namespace folly |
87 | |