proxygen
AsyncTimeoutSet.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree. An additional grant
7  * of patent rights can be found in the PATENTS file in the same directory.
8  *
9  */
10 #pragma once
11 
12 #include <chrono>
13 #include <cstddef>
17 #include <memory>
19 
20 namespace proxygen {
21 
42  public:
43  using UniquePtr = std::unique_ptr<AsyncTimeoutSet, Destructor>;
44 
54  class Callback {
55  public:
56  Callback() {}
57 
58  virtual ~Callback();
59 
63  virtual void timeoutExpired() noexcept = 0;
64 
70  void cancelTimeout() {
71  if (timeoutSet_ == nullptr) {
72  // We're not scheduled, so there's nothing to do.
73  return;
74  }
76  }
77 
81  bool isScheduled() const {
82  return timeoutSet_ != nullptr;
83  }
84 
85  private:
86  // Get the time remaining until this timeout expires
87  std::chrono::milliseconds getTimeRemaining(
88  std::chrono::milliseconds now) const {
89  if (now >= expiration_) {
90  return std::chrono::milliseconds(0);
91  }
92  return expiration_ - now;
93  }
94 
95  void setScheduled(AsyncTimeoutSet* timeoutSet, Callback* prev);
96  void cancelTimeoutImpl();
97 
98  std::shared_ptr<folly::RequestContext> context_;
99 
101  Callback* prev_{nullptr};
102  Callback* next_{nullptr};
103  std::chrono::milliseconds expiration_{0};
104 
105  // Give AsyncTimeoutSet direct access to our members so it can take care
106  // of scheduling/cancelling.
107  friend class AsyncTimeoutSet;
108  };
109 
114  class TimeoutClock {
115  public:
117 
118  virtual ~TimeoutClock() {}
119 
120  virtual std::chrono::milliseconds millisecondsSinceEpoch() = 0;
121  };
122 
128  AsyncTimeoutSet(folly::TimeoutManager* timeoutManager,
129  std::chrono::milliseconds intervalMS,
130  std::chrono::milliseconds atMostEveryN =
131  std::chrono::milliseconds(0),
132  TimeoutClock* timeoutClock = nullptr);
133 
139  AsyncTimeoutSet(folly::TimeoutManager* timeoutManager,
140  InternalEnum internal,
141  std::chrono::milliseconds intervalMS,
142  std::chrono::milliseconds atMostEveryN =
143  std::chrono::milliseconds(0));
144 
154  void destroy() override;
155 
163  std::chrono::milliseconds getInterval() const {
164  return interval_;
165  }
166 
174  void scheduleTimeout(Callback* callback);
175 
179  void fireAtMostEvery(const std::chrono::milliseconds& ms) {
180  atMostEveryN_ = ms;
181  }
182 
186  Callback* front() { return head_; }
187  const Callback* front() const { return head_; }
188 
189  protected:
196  ~AsyncTimeoutSet() override;
197 
198  private:
199  // Forbidden copy constructor and assignment operator
200  AsyncTimeoutSet(AsyncTimeoutSet const &) = delete;
201  AsyncTimeoutSet& operator=(AsyncTimeoutSet const &) = delete;
202 
203  // Private methods to be invoked by AsyncTimeoutSet::Callback
204  void headChanged();
205 
206  // Methods inherited from AsyncTimeout
207  void timeoutExpired() noexcept override;
208 
212  std::chrono::milliseconds interval_;
213  std::chrono::milliseconds atMostEveryN_;
214  bool inTimeoutExpired_{false};
215 };
216 
217 } // proxygen
std::chrono::milliseconds getInterval() const
void scheduleTimeout(Callback *callback)
AsyncTimeoutSet & operator=(AsyncTimeoutSet const &)=delete
std::chrono::steady_clock::time_point now()
std::shared_ptr< folly::RequestContext > context_
virtual void timeoutExpired() noexcept=0
requires E e noexcept(noexcept(s.error(std::move(e))))
void fireAtMostEvery(const std::chrono::milliseconds &ms)
std::chrono::milliseconds expiration_
std::chrono::milliseconds atMostEveryN_
std::chrono::milliseconds getTimeRemaining(std::chrono::milliseconds now) const
void setScheduled(AsyncTimeoutSet *timeoutSet, Callback *prev)
std::chrono::milliseconds millisecondsSinceEpoch()
Definition: Time.h:56
std::unique_ptr< AsyncTimeoutSet, Destructor > UniquePtr
std::chrono::milliseconds interval_
const Callback * front() const