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 <atomic>
20 
21 #include <glog/logging.h>
22 
23 #include <folly/executors/ScheduledExecutor.h>
24 #include <folly/futures/Future.h>
25 
26 namespace folly {
27 
28 struct FOLLY_EXPORT TimekeeperScheduledExecutorNoTimekeeper
29     : public std::logic_error {
TimekeeperScheduledExecutorNoTimekeeperTimekeeperScheduledExecutorNoTimekeeper30   TimekeeperScheduledExecutorNoTimekeeper()
31       : std::logic_error("No Timekeeper available") {}
32 };
33 
34 // This class turns a Executor into a ScheduledExecutor.
35 class TimekeeperScheduledExecutor : public ScheduledExecutor {
36  public:
37   TimekeeperScheduledExecutor(TimekeeperScheduledExecutor const&) = delete;
38   TimekeeperScheduledExecutor& operator=(TimekeeperScheduledExecutor const&) =
39       delete;
40   TimekeeperScheduledExecutor(TimekeeperScheduledExecutor&&) = delete;
41   TimekeeperScheduledExecutor& operator=(TimekeeperScheduledExecutor&&) =
42       delete;
43 
44   static Executor::KeepAlive<TimekeeperScheduledExecutor> create(
45       Executor::KeepAlive<> parent,
46       Function<std::shared_ptr<Timekeeper>()> getTimekeeper =
47           detail::getTimekeeperSingleton);
48 
49   virtual void add(Func func) override;
50 
51   virtual void scheduleAt(
52       Func&& func, ScheduledExecutor::TimePoint const& t) override;
53 
54  protected:
55   bool keepAliveAcquire() noexcept override;
56   void keepAliveRelease() noexcept override;
57 
58  private:
TimekeeperScheduledExecutor(KeepAlive<Executor> && parent,Function<std::shared_ptr<Timekeeper> ()> getTimekeeper)59   TimekeeperScheduledExecutor(
60       KeepAlive<Executor>&& parent,
61       Function<std::shared_ptr<Timekeeper>()> getTimekeeper)
62       : parent_(std::move(parent)), getTimekeeper_(std::move(getTimekeeper)) {}
63 
~TimekeeperScheduledExecutor()64   ~TimekeeperScheduledExecutor() { DCHECK(!keepAliveCounter_); }
65 
66   void run(Func);
67 
68   KeepAlive<Executor> parent_;
69   Function<std::shared_ptr<Timekeeper>()> getTimekeeper_;
70   std::atomic<ssize_t> keepAliveCounter_{1};
71 };
72 
73 } // namespace folly
74