1 /* 2 * Copyright (c) Facebook, Inc. and its affiliates. 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 { wrapFunc(Func f)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()() { f_(); } 40 41 private: 42 Executor::KeepAlive<VirtualExecutor> keepAlive_; 43 Func f_; 44 }; 45 46 return FuncAndKeepAlive(std::move(f), this); 47 } 48 49 public: VirtualExecutor(KeepAlive<> executor)50 explicit VirtualExecutor(KeepAlive<> executor) 51 : executor_(std::move(executor)) { 52 assert(!isKeepAliveDummy(executor_)); 53 } 54 VirtualExecutor(Executor * executor)55 explicit VirtualExecutor(Executor* executor) 56 : VirtualExecutor(getKeepAliveToken(executor)) {} 57 VirtualExecutor(Executor & executor)58 explicit VirtualExecutor(Executor& executor) 59 : VirtualExecutor(getKeepAliveToken(executor)) {} 60 61 VirtualExecutor(const VirtualExecutor&) = delete; 62 VirtualExecutor& operator=(const VirtualExecutor&) = delete; 63 getNumPriorities()64 uint8_t getNumPriorities() const override { 65 return executor_->getNumPriorities(); 66 } 67 add(Func f)68 void add(Func f) override { executor_->add(wrapFunc(std::move(f))); } 69 addWithPriority(Func f,int8_t priority)70 void addWithPriority(Func f, int8_t priority) override { 71 executor_->addWithPriority(wrapFunc(std::move(f)), priority); 72 } 73 ~VirtualExecutor()74 ~VirtualExecutor() override { joinKeepAlive(); } 75 76 private: 77 const KeepAlive<> executor_; 78 }; 79 80 } // namespace folly 81