Log (de)compression bytes
[folly.git] / folly / executors / TimedDrivableExecutor.h
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 <chrono>
20
21 #include <folly/concurrency/UnboundedQueue.h>
22 #include <folly/executors/DrivableExecutor.h>
23
24 namespace folly {
25
26 /*
27  * A DrivableExecutor can be driven via its drive() method or its driveUntil()
28  * that drives until some time point.
29  */
30 class TimedDrivableExecutor : public DrivableExecutor {
31  public:
32   /// Implements DrivableExecutor
33   void drive() override;
34
35   // Make progress if there is work to do and return true. Otherwise return
36   // false.
37   bool try_drive() {
38     return try_wait() && run() > 0;
39   }
40
41   // Make progress on this Executor's work. Acts as drive, except it will only
42   // wait for a period of timeout for work to be enqueued. If no work is
43   // enqueued by that point, it will return.
44   template <typename Rep, typename Period>
45   bool try_drive_for(const std::chrono::duration<Rep, Period>& timeout) {
46     return try_wait_for(timeout) && run() > 0;
47   }
48
49   // Make progress on this Executor's work. Acts as drive, except it will only
50   // wait until deadline for work to be enqueued. If no work is enqueued by
51   // that point, it will return.
52   template <typename Clock, typename Duration>
53   bool try_drive_until(
54       const std::chrono::time_point<Clock, Duration>& deadline) {
55     return try_wait_until(deadline) && run() > 0;
56   }
57
58   void add(Func) override;
59
60   /// Do work. Returns the number of functions that were executed (maybe 0).
61   /// Non-blocking, in the sense that we don't wait for work (we can't
62   /// control whether one of the functions blocks).
63   /// This is stable, it will not chase an ever-increasing tail of work.
64   /// This also means, there may be more work available to perform at the
65   /// moment that this returns.
66   size_t run();
67
68   // Do work until there is no more work to do.
69   // Returns the number of functions that were executed (maybe 0).
70   // Unlike run, this method is not stable. It will chase an infinite tail of
71   // work so should be used with care.
72   // There will be no work available to perform at the moment that this
73   // returns.
74   size_t drain();
75
76   /// Wait for work to do.
77   void wait();
78
79   // Return true if there is work to do, false otherwise
80   bool try_wait() {
81     return func_ || queue_.try_dequeue(func_);
82   }
83
84   /// Wait for work to do or for a period of timeout, whichever is sooner.
85   template <typename Rep, typename Period>
86   bool try_wait_for(const std::chrono::duration<Rep, Period>& timeout) {
87     return func_ || queue_.try_dequeue_for(func_, timeout);
88   }
89
90   /// Wait for work to do or until deadline passes, whichever is sooner.
91   template <typename Clock, typename Duration>
92   bool try_wait_until(
93       const std::chrono::time_point<Clock, Duration>& deadline) {
94     return func_ || queue_.try_dequeue_until(func_, deadline);
95   }
96
97  private:
98   UMPSCQueue<Func, true> queue_;
99   Func func_;
100 };
101
102 } // namespace folly