proxygen
Baton.h
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  */
16 #pragma once
17 
18 #include <atomic>
19 
20 #include <folly/Portability.h>
21 #include <folly/detail/Futex.h>
23 
24 #if FOLLY_HAS_COROUTINES
25 #include <experimental/coroutine>
26 #endif
27 
28 namespace folly {
29 namespace fibers {
30 
31 class Fiber;
32 class FiberManager;
33 
40 class Baton {
41  public:
42  class TimeoutHandler;
43 
44  class Waiter {
45  public:
46  virtual void post() = 0;
47 
48  virtual ~Waiter() {}
49  };
50 
51  Baton() noexcept;
52 
53  ~Baton() noexcept = default;
54 
55  bool ready() const {
56  auto state = waiter_.load();
57  return state == POSTED;
58  }
59 
64  void setWaiter(Waiter& waiter);
65 
69  void wait();
70 
78  void wait(TimeoutHandler& timeoutHandler);
79 
86  template <typename F>
87  void wait(F&& mainContextFunc);
88 
94  bool try_wait();
95 
104  template <typename Rep, typename Period>
105  bool try_wait_for(const std::chrono::duration<Rep, Period>& timeout) {
106  return try_wait_for(timeout, [] {});
107  }
108 
119  template <typename Rep, typename Period, typename F>
120  bool try_wait_for(
121  const std::chrono::duration<Rep, Period>& timeout,
122  F&& mainContextFunc);
123 
132  template <typename Clock, typename Duration>
134  const std::chrono::time_point<Clock, Duration>& deadline) {
135  return try_wait_until(deadline, [] {});
136  }
137 
148  template <typename Clock, typename Duration, typename F>
149  bool try_wait_until(
150  const std::chrono::time_point<Clock, Duration>& deadline,
151  F&& mainContextFunc);
152 
163  template <typename Clock, typename Duration, typename F>
164  bool try_wait_for(
165  const std::chrono::time_point<Clock, Duration>& deadline,
166  F&& mainContextFunc);
167 
169  template <typename Rep, typename Period>
170  bool timed_wait(const std::chrono::duration<Rep, Period>& timeout) {
171  return try_wait_for(timeout);
172  }
173 
175  template <typename Rep, typename Period, typename F>
177  const std::chrono::duration<Rep, Period>& timeout,
178  F&& mainContextFunc) {
179  return try_wait_for(timeout, static_cast<F&&>(mainContextFunc));
180  }
181 
183  template <typename Clock, typename Duration>
184  bool timed_wait(const std::chrono::time_point<Clock, Duration>& deadline) {
185  return try_wait_until(deadline);
186  }
187 
189  template <typename Clock, typename Duration, typename F>
191  const std::chrono::time_point<Clock, Duration>& deadline,
192  F&& mainContextFunc) {
193  return try_wait_until(deadline, static_cast<F&&>(mainContextFunc));
194  }
195 
200  void post();
201 
208  void reset();
209 
219  public:
220  void scheduleTimeout(TimeoutController::Duration timeoutMs);
221 
222  private:
223  friend class Baton;
224 
225  void cancelTimeout();
226 
227  std::function<void()> timeoutFunc_{nullptr};
228  FiberManager* fiberManager_{nullptr};
229 
230  intptr_t timeoutPtr_{0};
231  };
232 
233  private:
234  class FiberWaiter;
235 
236  enum {
253  };
254 
255  explicit Baton(intptr_t state) : waiter_(state) {}
256 
257  void postHelper(intptr_t new_value);
258  void postThread();
259  void waitThread();
260 
261  template <typename F>
262  inline void waitFiber(FiberManager& fm, F&& mainContextFunc);
269  bool spinWaitForEarlyPost();
270 
272 
273  static constexpr intptr_t NO_WAITER = 0;
274  static constexpr intptr_t POSTED = -1;
275  static constexpr intptr_t TIMEOUT = -2;
276  static constexpr intptr_t THREAD_WAITING = -3;
277 
278  union {
279  std::atomic<intptr_t> waiter_;
280  struct {
283  } futex_;
284  };
285 };
286 
287 #if FOLLY_HAS_COROUTINES
288 namespace detail {
289 class BatonAwaitableWaiter : public Baton::Waiter {
290  public:
291  explicit BatonAwaitableWaiter(Baton& baton) : baton_(baton) {}
292 
293  void post() override {
294  assert(h_);
295  h_();
296  }
297 
298  bool await_ready() const {
299  return baton_.ready();
300  }
301 
302  void await_resume() {}
303 
304  void await_suspend(std::experimental::coroutine_handle<> h) {
305  assert(!h_);
306  h_ = std::move(h);
307  baton_.setWaiter(*this);
308  }
309 
310  private:
311  std::experimental::coroutine_handle<> h_;
312  Baton& baton_;
313 };
314 } // namespace detail
315 
316 inline detail::BatonAwaitableWaiter /* implicit */ operator co_await(
317  Baton& baton) {
318  return detail::BatonAwaitableWaiter(baton);
319 }
320 #endif
321 } // namespace fibers
322 } // namespace folly
323 
324 #include <folly/fibers/Baton-inl.h>
static constexpr intptr_t NO_WAITER
Definition: Baton.h:273
static constexpr intptr_t POSTED
Definition: Baton.h:274
*than *hazptr_holder h
Definition: Hazptr.h:116
Baton() noexcept
Definition: Baton-inl.h:37
static constexpr intptr_t TIMEOUT
Definition: Baton.h:275
struct folly::fibers::Baton::@51::@53 futex_
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
Atom< std::uint32_t > Futex
Definition: Futex.h:51
int32_t _unused_packing
Definition: Baton.h:282
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
requires E e noexcept(noexcept(s.error(std::move(e))))
std::atomic< intptr_t > waiter_
Definition: Baton.h:279
Single-threaded task execution engine.
static constexpr intptr_t THREAD_WAITING
Definition: Baton.h:276
bool timed_wait(const std::chrono::time_point< Clock, Duration > &deadline, F &&mainContextFunc)
Alias to try_wait_until. Deprecated.
Definition: Baton.h:190
bool timed_wait(const std::chrono::time_point< Clock, Duration > &deadline)
Alias to try_wait_until. Deprecated.
Definition: Baton.h:184
Baton(intptr_t state)
Definition: Baton.h:255
bool timedWaitThread(TimeoutController::Duration timeout)
Definition: Baton.cpp:113
bool timed_wait(const std::chrono::duration< Rep, Period > &timeout, F &&mainContextFunc)
Alias to try_wait_for. Deprecated.
Definition: Baton.h:176
void setWaiter(Waiter &waiter)
Definition: Baton.cpp:30
folly::detail::Futex futex
Definition: Baton.h:281
~Baton() noexcept=default
bool try_wait_until(const std::chrono::time_point< Clock, Duration > &deadline)
Definition: Baton.h:133
void waitFiber(FiberManager &fm, F &&mainContextFunc)
Definition: Baton-inl.h:61
bool ready() const
Definition: Baton.h:55
bool try_wait_for(const std::chrono::duration< Rep, Period > &timeout)
Definition: Baton.h:105
void postHelper(intptr_t new_value)
Definition: Baton.cpp:154
state
Definition: http_parser.c:272
bool spinWaitForEarlyPost()
Definition: Baton.cpp:94
bool timed_wait(const std::chrono::duration< Rep, Period > &timeout)
Alias to try_wait_for. Deprecated.
Definition: Baton.h:170