proxygen
EventBaseLoopController-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/Memory.h>
18 
19 namespace folly {
20 namespace fibers {
21 
23 
26  eventBaseKeepAlive_.reset();
27 }
28 
31 }
32 
34  VirtualEventBase& eventBase) {
35  if (eventBase_ != nullptr) {
36  LOG(ERROR) << "Attempt to reattach EventBase to LoopController";
37  }
38 
39  eventBase_ = &eventBase;
40  eventBaseAttached_ = true;
41 
42  if (awaitingScheduling_) {
43  schedule();
44  }
45 }
46 
48  fm_ = fm;
49 }
50 
52  if (eventBase_ == nullptr) {
53  // In this case we need to postpone scheduling.
54  awaitingScheduling_ = true;
55  } else {
56  // Schedule it to run in current iteration.
57 
58  if (!eventBaseKeepAlive_) {
60  }
62  awaitingScheduling_ = false;
63  }
64 }
65 
67  if (!eventBaseKeepAlive_) {
68  // runLoop can be called twice if both schedule() and scheduleThreadSafe()
69  // were called.
70  if (!fm_->hasTasks()) {
71  return;
72  }
74  }
75  if (loopRunner_) {
76  if (fm_->hasReadyTasks()) {
78  }
79  } else {
81  }
82  if (!fm_->hasTasks()) {
83  eventBaseKeepAlive_.reset();
84  }
85 }
86 
88  /* The only way we could end up here is if
89  1) Fiber thread creates a fiber that awaits (which means we must
90  have already attached, fiber thread wouldn't be running).
91  2) We move the promise to another thread (this move is a memory fence)
92  3) We fulfill the promise from the other thread. */
93  assert(eventBaseAttached_);
94 
96  [this, eventBaseKeepAlive = getKeepAliveToken(eventBase_)]() {
97  if (fm_->shouldRunLoopRemote()) {
98  return runLoop();
99  }
100 
101  if (!fm_->hasTasks()) {
102  eventBaseKeepAlive_.reset();
103  }
104  });
105 }
106 
108  std::function<void()> func,
109  TimePoint time) {
110  assert(eventBaseAttached_);
111 
112  // We want upper bound for the cast, thus we just add 1
113  auto delay_ms =
114  std::chrono::duration_cast<std::chrono::milliseconds>(time - Clock::now())
115  .count() +
116  1;
117  // If clock is not monotonic
118  delay_ms = std::max<decltype(delay_ms)>(delay_ms, 0);
119  eventBase_->tryRunAfterDelay(func, uint32_t(delay_ms));
120 }
121 } // namespace fibers
122 } // namespace folly
void timedSchedule(std::function< void()> func, TimePoint time) override
Executor::KeepAlive< VirtualEventBase > eventBaseKeepAlive_
void runInEventBaseThread(F &&f)
std::chrono::steady_clock::time_point now()
bool tryRunAfterDelay(Func cob, uint32_t milliseconds, InternalEnum internal=InternalEnum::NORMAL)
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
virtual void run(folly::Function< void()> func)=0
std::chrono::time_point< Clock > TimePoint
Single-threaded task execution engine.
void runInLoop(LoopCallback *callback, bool thisIteration=false)
Definition: EventBase.cpp:520
void setFiberManager(FiberManager *fm) override
int * count
folly::Function< void()> callback_
Executor::KeepAlive< ExecutorT > getKeepAliveToken(ExecutorT *executor)
Definition: Executor.h:200
folly::VirtualEventBase & getVirtualEventBase()
Definition: EventBase.cpp:768
std::chrono::nanoseconds time()