proxygen
Utils.h
Go to the documentation of this file.
1 /*
2  * Copyright 2017-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 <experimental/coroutine>
19 #include <future>
20 #include <type_traits>
21 
22 #include <folly/Optional.h>
25 #include <folly/futures/Future.h>
26 
27 namespace folly {
28 namespace coro {
29 
30 template <typename T>
32  public:
35  : value_(static_cast<T&&>(value)) {}
36 
38  return true;
39  }
40 
41  void await_suspend(std::experimental::coroutine_handle<>) noexcept {}
42 
43  T await_resume() noexcept(std::is_nothrow_move_constructible<T>::value) {
44  return static_cast<T&&>(value_);
45  }
46 
47  private:
49 };
50 
51 template <>
52 class AwaitableReady<void> {
53  public:
54  AwaitableReady() noexcept = default;
56  return true;
57  }
58  void await_suspend(std::experimental::coroutine_handle<>) noexcept {}
60 };
61 
62 template <typename Awaitable>
64  public:
65  static_assert(
66  std::is_same<Awaitable, std::decay_t<Awaitable>>::value,
67  "Awaitable should be decayed.");
69 
70  TimedWaitAwaitable(Awaitable&& awaitable, std::chrono::milliseconds duration)
71  : awaitable_(std::move(awaitable)), duration_(duration) {}
72 
73  bool await_ready() {
74  return false;
75  }
76 
77  bool await_suspend(std::experimental::coroutine_handle<> ch) {
78  auto sharedState = std::make_shared<SharedState>(ch, storage_);
79  waitAndNotify(std::move(awaitable_), sharedState).detach();
80  futures::sleep(duration_).thenValue(
81  [sharedState = std::move(sharedState)](Unit) {
82  sharedState->setTimeout();
83  });
84  return true;
85  }
86 
88  if (!storage_.hasValue() && !storage_.hasException()) {
89  return folly::none;
90  }
91  return std::move(storage_).value();
92  }
93 
94  private:
95  class SharedState {
96  public:
98  std::experimental::coroutine_handle<> ch,
100  : ch_(std::move(ch)), storage_(storage) {}
101 
103  if (first_.exchange(true, std::memory_order_relaxed)) {
104  return;
105  }
106  assume(!storage_.hasValue() && !storage_.hasException());
107  tryEmplace(storage_, static_cast<await_resume_return_type&&>(value));
108  ch_();
109  }
110 
112  if (first_.exchange(true, std::memory_order_relaxed)) {
113  return;
114  }
115  assume(!storage_.hasValue() && !storage_.hasException());
116  storage_.emplaceException(std::move(e));
117  ch_();
118  }
119 
120  void setTimeout() {
121  if (first_.exchange(true, std::memory_order_relaxed)) {
122  return;
123  }
124  ch_();
125  }
126 
127  private:
128  std::atomic<bool> first_{false};
129  std::experimental::coroutine_handle<> ch_;
131  };
132 
134  Awaitable awaitable,
135  std::shared_ptr<SharedState> sharedState) {
136  try {
137  sharedState->setValue(co_await std::forward<Awaitable>(awaitable));
138  } catch (const std::exception& e) {
139  sharedState->setException(exception_wrapper(std::current_exception(), e));
140  } catch (...) {
141  sharedState->setException(exception_wrapper(std::current_exception()));
142  }
143  }
144 
145  Awaitable awaitable_;
146  std::chrono::milliseconds duration_;
148 };
149 
150 template <typename Awaitable>
152  Awaitable&& awaitable,
153  std::chrono::milliseconds duration) {
155  std::forward<Awaitable>(awaitable), duration);
156 }
157 
158 } // namespace coro
159 } // namespace folly
await_result_t< Awaitable > await_resume_return_type
Definition: Utils.h:68
T * tryEmplace(Try< T > &t, Args &&...args) noexcept
Definition: Try-inl.h:249
void await_resume() noexcept
Definition: Utils.h:59
void await_suspend(std::experimental::coroutine_handle<>) noexcept
Definition: Utils.h:58
T await_resume() noexcept(std::is_nothrow_move_constructible< T >::value)
Definition: Utils.h:43
std::experimental::coroutine_handle ch_
Definition: Utils.h:129
bool await_ready() noexcept
Definition: Utils.h:37
void setException(exception_wrapper e)
Definition: Utils.h:111
Future< Unit > sleep(Duration dur, Timekeeper *tk)
Definition: Future.cpp:42
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
STL namespace.
AwaitableReady(T value) noexcept(std::is_nothrow_move_constructible< T >::value)
Definition: Utils.h:33
folly::std T
Optional< await_resume_return_type > await_resume()
Definition: Utils.h:87
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
bool await_ready() noexcept
Definition: Utils.h:55
SharedState(std::experimental::coroutine_handle<> ch, Try< await_resume_return_type > &storage)
Definition: Utils.h:97
TimedWaitAwaitable< std::decay_t< Awaitable > > timed_wait(Awaitable &&awaitable, std::chrono::milliseconds duration)
Definition: Utils.h:151
requires E e noexcept(noexcept(s.error(std::move(e))))
typename await_result< Awaitable >::type await_result_t
Definition: Traits.h:194
auto ch
std::chrono::milliseconds duration_
Definition: Utils.h:146
void setValue(await_resume_return_type &&value)
Definition: Utils.h:102
static const char *const value
Definition: Conv.cpp:50
TimedWaitAwaitable(Awaitable &&awaitable, std::chrono::milliseconds duration)
Definition: Utils.h:70
Try< await_resume_return_type > & storage_
Definition: Utils.h:130
void await_suspend(std::experimental::coroutine_handle<>) noexcept
Definition: Utils.h:41
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
Try< await_resume_return_type > storage_
Definition: Utils.h:147
FOLLY_ALWAYS_INLINE void assume(bool cond)
Definition: Assume.h:41
static Wait waitAndNotify(Awaitable awaitable, std::shared_ptr< SharedState > sharedState)
Definition: Utils.h:133
bool await_suspend(std::experimental::coroutine_handle<> ch)
Definition: Utils.h:77
constexpr None none
Definition: Optional.h:87