Log (de)compression bytes
[folly.git] / folly / executors / SerialExecutor.h
1 /*
2  * Copyright 2017-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 <memory>
20
21 #include <folly/Executor.h>
22 #include <folly/executors/GlobalExecutor.h>
23
24 namespace folly {
25
26 /**
27  * @class SerialExecutor
28  *
29  * @brief Executor that guarantees serial non-concurrent execution of added
30  *     tasks
31  *
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
36  * they were added.
37  *
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.
43  *
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.
47  */
48
49 class SerialExecutor : public folly::Executor {
50  public:
51   ~SerialExecutor() override = default;
52   SerialExecutor(SerialExecutor const&) = delete;
53   SerialExecutor& operator=(SerialExecutor const&) = delete;
54   SerialExecutor(SerialExecutor&&) = default;
55   SerialExecutor& operator=(SerialExecutor&&) = default;
56
57   explicit SerialExecutor(
58       std::shared_ptr<folly::Executor> parent = folly::getCPUExecutor());
59
60   /**
61    * Add one task for execution in the parent executor
62    */
63   void add(Func func) override;
64
65   /**
66    * Add one task for execution in the parent executor, and use the given
67    * priority for one task submission to parent executor.
68    *
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.
74    */
75   void addWithPriority(Func func, int8_t priority) override;
76   uint8_t getNumPriorities() const override {
77     return parent_->getNumPriorities();
78   }
79
80  private:
81   class TaskQueueImpl;
82
83   std::shared_ptr<folly::Executor> parent_;
84   std::shared_ptr<TaskQueueImpl> taskQueueImpl_;
85 };
86
87 } // namespace folly