2 * Copyright 2017-present 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.
21 #include <folly/Executor.h>
22 #include <folly/executors/GlobalExecutor.h>
27 * @class SerialExecutor
29 * @brief Executor that guarantees serial non-concurrent execution of added
32 * SerialExecutor is similar to boost asio's strand concept. A SerialExecutor
33 * has a parent executor which is given at construction time (defaults to
34 * folly's global CPUExecutor). Tasks added to SerialExecutor are executed
35 * in the parent executor, however strictly non-concurrently and in the order
38 * SerialExecutor tries to schedule its tasks fairly. Every task submitted to
39 * it results in one task submitted to the parent executor. Whenever the parent
40 * executor executes one of those, one of the tasks submitted to SerialExecutor
41 * is marked for execution, which means it will either be executed at once,
42 * or if a task is currently being executed already, after that.
44 * The SerialExecutor may be deleted at any time. All tasks that have been
45 * submitted will still be executed with the same guarantees, as long as the
46 * parent executor is executing tasks.
49 class SerialExecutor : public folly::Executor {
51 ~SerialExecutor() override = default;
52 SerialExecutor(SerialExecutor const&) = delete;
53 SerialExecutor& operator=(SerialExecutor const&) = delete;
54 SerialExecutor(SerialExecutor&&) = default;
55 SerialExecutor& operator=(SerialExecutor&&) = default;
57 explicit SerialExecutor(
58 std::shared_ptr<folly::Executor> parent = folly::getCPUExecutor());
61 * Add one task for execution in the parent executor
63 void add(Func func) override;
66 * Add one task for execution in the parent executor, and use the given
67 * priority for one task submission to parent executor.
69 * Since in-order execution of tasks submitted to SerialExecutor is
70 * guaranteed, the priority given here does not necessarily reflect the
71 * execution priority of the task submitted with this call to
72 * `addWithPriority`. The given priority is passed on to the parent executor
73 * for the execution of one of the SerialExecutor's tasks.
75 void addWithPriority(Func func, int8_t priority) override;
76 uint8_t getNumPriorities() const override {
77 return parent_->getNumPriorities();
83 std::shared_ptr<folly::Executor> parent_;
84 std::shared_ptr<TaskQueueImpl> taskQueueImpl_;