proxygen
Baton.h
Go to the documentation of this file.
1 /*
2  * Copyright 2018-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 #include <experimental/coroutine>
20 
21 namespace folly {
22 namespace coro {
23 
55 class Baton {
56  public:
57  class WaitOperation;
58 
60  explicit Baton(bool initiallySignalled = false) noexcept;
61 
62  ~Baton();
63 
65  bool ready() const noexcept;
66 
81  [[nodiscard]] WaitOperation operator co_await() const noexcept;
82 
87  void post() noexcept;
88 
95  void reset() noexcept;
96 
97  class WaitOperation {
98  public:
99  explicit WaitOperation(const Baton& baton) noexcept : baton_(baton) {}
100 
101  bool await_ready() const noexcept {
102  return baton_.ready();
103  }
104 
106  std::experimental::coroutine_handle<> awaitingCoroutine) noexcept {
107  awaitingCoroutine_ = awaitingCoroutine;
108  return baton_.waitImpl(this);
109  }
110 
111  void await_resume() noexcept {}
112 
113  protected:
114  friend class Baton;
115 
116  const Baton& baton_;
117  std::experimental::coroutine_handle<> awaitingCoroutine_;
119  };
120 
121  private:
122  // Try to register the awaiter as
123  bool waitImpl(WaitOperation* awaiter) const noexcept;
124 
125  // this - Baton is in the signalled/posted state.
126  // other - Baton is not signalled/posted and this is a pointer to the head
127  // of a potentially empty linked-list of Awaiter nodes that were
128  // waiting for the baton to become signalled.
129  mutable std::atomic<void*> state_;
130 };
131 
132 inline Baton::Baton(bool initiallySignalled) noexcept
133  : state_(initiallySignalled ? static_cast<void*>(this) : nullptr) {}
134 
135 inline bool Baton::ready() const noexcept {
136  return state_.load(std::memory_order_acquire) ==
137  static_cast<const void*>(this);
138 }
139 
140 inline Baton::WaitOperation Baton::operator co_await() const noexcept {
141  return Baton::WaitOperation{*this};
142 }
143 
144 inline void Baton::reset() noexcept {
145  state_.store(nullptr, std::memory_order_relaxed);
146 }
147 
148 } // namespace coro
149 } // namespace folly
bool await_suspend(std::experimental::coroutine_handle<> awaitingCoroutine) noexcept
Definition: Baton.h:105
bool waitImpl(WaitOperation *awaiter) const noexcept
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
requires E e noexcept(noexcept(s.error(std::move(e))))
void post() noexcept
std::atomic< void * > state_
Definition: Baton.h:129
bool await_ready() const noexcept
Definition: Baton.h:101
Baton(bool initiallySignalled=false) noexcept
Initialise the Baton to either the signalled or non-signalled state.
Definition: Baton.h:132
WaitOperation(const Baton &baton) noexcept
Definition: Baton.h:99
bool ready() const noexcept
Query whether the Baton is currently in the signalled state.
Definition: Baton.h:135
const
Definition: upload.py:398
void await_resume() noexcept
Definition: Baton.h:111
std::experimental::coroutine_handle awaitingCoroutine_
Definition: Baton.h:117
void reset() noexcept
Definition: Baton.h:144