proxygen
Baton-inl.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 #include <folly/fibers/Fiber.h>
18 
19 namespace folly {
20 namespace fibers {
21 
23  public:
24  void setFiber(Fiber& fiber) {
25  DCHECK(!fiber_);
26  fiber_ = &fiber;
27  }
28 
29  void post() override {
30  fiber_->resume();
31  }
32 
33  private:
34  Fiber* fiber_{nullptr};
35 };
36 
38  assert(Baton(NO_WAITER).futex_.futex == static_cast<uint32_t>(NO_WAITER));
39  assert(Baton(POSTED).futex_.futex == static_cast<uint32_t>(POSTED));
40  assert(Baton(TIMEOUT).futex_.futex == static_cast<uint32_t>(TIMEOUT));
41  assert(
42  Baton(THREAD_WAITING).futex_.futex ==
43  static_cast<uint32_t>(THREAD_WAITING));
44 
45  assert(futex_.futex.is_lock_free());
46  assert(waiter_.is_lock_free());
47 }
48 
49 template <typename F>
50 void Baton::wait(F&& mainContextFunc) {
52  if (!fm || !fm->activeFiber_) {
53  mainContextFunc();
54  return waitThread();
55  }
56 
57  return waitFiber(*fm, std::forward<F>(mainContextFunc));
58 }
59 
60 template <typename F>
61 void Baton::waitFiber(FiberManager& fm, F&& mainContextFunc) {
62  FiberWaiter waiter;
63  auto f = [this, &mainContextFunc, &waiter](Fiber& fiber) mutable {
64  waiter.setFiber(fiber);
65  setWaiter(waiter);
66 
67  mainContextFunc();
68  };
69 
70  fm.awaitFunc_ = std::ref(f);
72 }
73 
74 template <typename Rep, typename Period, typename F>
76  const std::chrono::duration<Rep, Period>& timeout,
77  F&& mainContextFunc) {
79 
80  if (!fm || !fm->activeFiber_) {
81  mainContextFunc();
82  return timedWaitThread(timeout);
83  }
84 
85  auto& baton = *this;
86  bool canceled = false;
87  auto timeoutFunc = [&baton, &canceled]() mutable {
88  baton.postHelper(TIMEOUT);
89  canceled = true;
90  };
91 
92  auto id =
93  fm->timeoutManager_->registerTimeout(std::ref(timeoutFunc), timeout);
94 
95  waitFiber(*fm, static_cast<F&&>(mainContextFunc));
96 
97  auto posted = waiter_ == POSTED;
98 
99  if (!canceled) {
100  fm->timeoutManager_->cancel(id);
101  }
102 
103  return posted;
104 }
105 
106 template <typename Clock, typename Duration, typename F>
108  const std::chrono::time_point<Clock, Duration>& deadline,
109  F&& mainContextFunc) {
110  auto now = Clock::now();
111 
112  if (LIKELY(now <= deadline)) {
113  return try_wait_for(deadline - now, static_cast<F&&>(mainContextFunc));
114  } else {
115  return try_wait_for(Duration{}, static_cast<F&&>(mainContextFunc));
116  }
117 }
118 } // namespace fibers
119 } // namespace folly
static constexpr intptr_t NO_WAITER
Definition: Baton.h:273
static constexpr intptr_t POSTED
Definition: Baton.h:274
auto f
folly::Function< void(Fiber &)> awaitFunc_
Baton() noexcept
Definition: Baton-inl.h:37
static constexpr intptr_t TIMEOUT
Definition: Baton.h:275
struct folly::fibers::Baton::@51::@53 futex_
std::chrono::steady_clock::time_point now()
#define LIKELY(x)
Definition: Likely.h:47
—— 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
Fiber object used by FiberManager to execute tasks.
Definition: Fiber.h:45
std::chrono::milliseconds Duration
Definition: Types.h:36
void preempt(State state)
Definition: Fiber.cpp:172
void setFiber(Fiber &fiber)
Definition: Baton-inl.h:24
bool timedWaitThread(TimeoutController::Duration timeout)
Definition: Baton.cpp:113
void setWaiter(Waiter &waiter)
Definition: Baton.cpp:30
static FiberManager * getFiberManagerUnsafe()
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 try_wait_for(const std::chrono::duration< Rep, Period > &timeout)
Definition: Baton.h:105