proxygen
TimeoutController.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2014-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  */
17 #include <folly/Memory.h>
18 
19 namespace folly {
20 namespace fibers {
21 
23  : nextTimeout_(TimePoint::max()), loopController_(loopController) {}
24 
26  std::function<void()> f,
27  Duration duration) {
28  auto& list = [&]() -> TimeoutHandleList& {
29  for (auto& bucket : timeoutHandleBuckets_) {
30  if (bucket.first == duration) {
31  return *bucket.second;
32  }
33  }
34 
35  timeoutHandleBuckets_.emplace_back(
36  duration, std::make_unique<TimeoutHandleList>());
37  return *timeoutHandleBuckets_.back().second;
38  }();
39 
40  auto timeout = Clock::now() + duration;
41  list.emplace(std::move(f), timeout, list);
42 
43  if (timeout < nextTimeout_) {
45  scheduleRun();
46  }
47 
48  return reinterpret_cast<intptr_t>(&list.back());
49 }
50 
52  auto now = Clock::now();
53  // Make sure we don't skip some events if function was run before actual time.
54  if (time < now) {
55  time = now;
56  }
57  if (nextTimeout_ > time) {
58  return;
59  }
60 
62 
63  for (auto& bucket : timeoutHandleBuckets_) {
64  auto& list = *bucket.second;
65 
66  while (!list.empty()) {
67  if (!list.front().canceled) {
68  if (list.front().timeout > time) {
69  nextTimeout_ = std::min(nextTimeout_, list.front().timeout);
70  break;
71  }
72 
73  list.front().func();
74  }
75  list.pop();
76  }
77  }
78 
79  if (nextTimeout_ != TimePoint::max()) {
80  scheduleRun();
81  }
82 }
83 
85  auto time = nextTimeout_;
86  std::weak_ptr<TimeoutController> timeoutControllerWeak = shared_from_this();
87 
89  [timeoutControllerWeak, time]() {
90  if (auto timeoutController = timeoutControllerWeak.lock()) {
91  timeoutController->runTimeouts(time);
92  }
93  },
94  time);
95 }
96 
97 void TimeoutController::cancel(intptr_t p) {
98  auto handle = reinterpret_cast<TimeoutHandle*>(p);
99  handle->canceled = true;
100 
101  auto& list = handle->list;
102 
103  while (!list.empty() && list.front().canceled) {
104  list.pop();
105  }
106 }
107 } // namespace fibers
108 } // namespace folly
auto f
LogLevel max
Definition: LogLevel.cpp:31
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::chrono::steady_clock::time_point now()
virtual void timedSchedule(std::function< void()> func, TimePoint time)=0
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
std::vector< std::pair< Duration, TimeoutHandleListPtr > > timeoutHandleBuckets_
LogLevel min
Definition: LogLevel.cpp:30
Encoder::MutableCompressedList list
intptr_t registerTimeout(std::function< void()> f, Duration duration)
TimeoutController(LoopController &loopController)
std::queue< TimeoutHandle > TimeoutHandleList
std::chrono::nanoseconds time()
std::chrono::time_point< Clock > TimePoint