39 inline FiberManager::Options preprocessOptions(FiberManager::Options opts) {
62 #ifdef FOLLY_SANITIZE_ADDRESS 63 DCHECK(!fiber->asanMainStackBase_);
64 DCHECK(!fiber->asanMainStackSize_);
67 registerStartSwitchStackWithAsan(&asanFakeStack, stack.first, stack.second);
69 registerFinishSwitchStackWithAsan(asanFakeStack,
nullptr,
nullptr);
70 fiber->asanMainStackBase_ =
nullptr;
71 fiber->asanMainStackSize_ = 0;
82 #ifdef FOLLY_SANITIZE_ADDRESS 83 DCHECK(fiber->asanMainStackBase_);
84 DCHECK(fiber->asanMainStackSize_);
86 registerStartSwitchStackWithAsan(
87 &fiber->asanFakeStack_,
88 fiber->asanMainStackBase_,
89 fiber->asanMainStackSize_);
91 registerFinishSwitchStackWithAsan(
92 fiber->asanFakeStack_,
93 &fiber->asanMainStackBase_,
94 &fiber->asanMainStackSize_);
95 fiber->asanFakeStack_ =
nullptr;
147 fiber->
func_ =
nullptr;
198 auto originalFiberManager =
this;
213 CHECK_EQ(
this, originalFiberManager);
216 bool hadRemote =
true;
227 if (hadRemoteFiber) {
233 std::unique_ptr<RemoteTask> task(taskPtr);
251 hadRemote = hadRemoteTask || hadRemoteFiber;
274 template <
typename F>
278 static constexpr
bool allocateInBuffer =
289 fm_.exceptionCallback_(
290 std::current_exception(),
"running Func functor");
292 if (allocateInBuffer) {
305 template <
typename F>
312 if (Helper::allocateInBuffer) {
313 auto funcLoc =
static_cast<typename
Helper::Func*
>(fiber->getUserBuffer());
314 new (funcLoc)
typename Helper::Func(std::forward<F>(func), *
this);
316 fiber->setFunction(std::ref(*funcLoc));
318 auto funcLoc =
new typename Helper::Func(std::forward<F>(func), *
this);
320 fiber->setFunction(std::ref(*funcLoc));
331 template <
typename F>
335 if (currentFm && currentFm->currentFiber_ &&
337 return std::make_unique<RemoteTask>(
338 std::forward<F>(func), currentFm->currentFiber_->localData_);
340 return std::make_unique<RemoteTask>(std::forward<F>(func));
347 template <
typename X>
351 template <
typename T>
358 template <
typename F,
typename G>
367 : finally_(
std::
move(finally)), fm_(fm) {}
373 fm_.exceptionCallback_(
374 std::current_exception(),
"running Finally functor");
377 if (allocateInBuffer) {
395 : func_(
std::
move(func)), result_(finally.result_) {}
400 if (allocateInBuffer) {
412 static constexpr
bool allocateInBuffer =
416 template <
typename F,
typename G>
422 "finally(arg): arg must be Try<T>&&");
426 typename std::remove_reference<
428 "finally(Try<T>&&): T must be convertible from func()'s return type");
438 if (Helper::allocateInBuffer) {
439 auto funcLoc =
static_cast<typename
Helper::Func*
>(fiber->getUserBuffer());
441 static_cast<typename Helper::Finally*
>(
static_cast<void*
>(funcLoc + 1));
443 new (finallyLoc)
typename Helper::Finally(std::forward<G>(
finally), *
this);
444 new (funcLoc)
typename Helper::Func(std::forward<F>(func), *finallyLoc);
446 fiber->setFunctionFinally(std::ref(*funcLoc), std::ref(*finallyLoc));
449 new typename Helper::Finally(std::forward<G>(
finally), *
this);
451 new typename Helper::Func(std::forward<F>(func), *finallyLoc);
453 fiber->setFunctionFinally(std::ref(*funcLoc), std::ref(*finallyLoc));
464 template <
typename F>
473 auto f = [&func, &result]()
mutable {
503 template <
typename T>
508 return localThread<T>();
511 template <
typename T>
514 static thread_local
T t;
516 #else // osx doesn't support thread_local 524 if (fm && fm->currentFiber_ && fm->localType_ ==
localType_) {
525 fiber.
localData_ = fm->currentFiber_->localData_;
530 template <
typename LocalT>
533 std::unique_ptr<LoopController> loopController__,
540 std::rethrow_exception(eptr);
541 }
catch (
const std::exception& e) {
542 LOG(
DFATAL) <<
"Exception " <<
typeid(e).
name() <<
" with message '" 543 << e.what() <<
"' was thrown in " 544 <<
"FiberManager with context '" <<
context <<
"'";
546 LOG(
DFATAL) <<
"Unknown exception was thrown in FiberManager with " 547 <<
"context '" <<
context <<
"'";
556 template <
typename F>
std::pair< void *, size_t > getStack() const
bool hasReadyTasks() const
void activateFiber(Fiber *fiber)
Func(F func, Finally &finally)
void deactivateFiber(Fiber *fiber)
static std::shared_ptr< RequestContext > setContext(std::shared_ptr< RequestContext > ctx)
folly::Function< void(Fiber &)> awaitFunc_
void ensureLoopScheduled()
static FOLLY_EXPORT T & localThread()
void addTaskRemote(F &&func)
typename invoke_result< F, Args... >::type invoke_result_t
FiberTailQueue readyFibers_
constexpr detail::Map< Move > move
invoke_result_t< F > runInMainContext(F &&func)
static FOLLY_TLS FiberManager * currentFiberManager_
void addTaskFinally(F &&func, G &&finally)
void registerAlternateSignalStack()
—— Concurrent Priority Queue Implementation ——
void setFunction(F &&func)
folly::Try< Result > result_
bool hasActiveFiber() const
static FiberManager & getFiberManager()
folly::Function< void()> resultFunc_
T * tryEmplaceWith(Try< T > &t, Func &&func) noexcept
virtual void runnable(uintptr_t id) noexcept=0
Func(F &&func, FiberManager &fm)
void loopUntilNoReadyImpl()
std::unique_ptr< LoopController > loopController_
Single-threaded task execution engine.
folly::Function< void()> func
static std::shared_ptr< RequestContext > saveContext()
Fiber object used by FiberManager to execute tasks.
void initLocalData(Fiber &fiber)
invoke_result_t< F > Result
std::shared_ptr< RequestContext > rcontext_
uint32_t fibersPoolResizePeriodMs
virtual void stopped(uintptr_t id) noexcept=0
void preempt(State state)
static constexpr size_t kUserBufferSize
ExecutionObserver * observer_
folly::Function< void()> func_
folly::Function< void()> finallyFunc_
FiberTailQueue fibersPool_
bool shouldRunLoopRemote()
virtual void starting(uintptr_t id) noexcept=0
std::shared_ptr< TimeoutController > timeoutManager_
void runReadyFiber(Fiber *fiber)
bool alternateSignalStackRegistered_
folly::AtomicIntrusiveLinkedList< Fiber,&Fiber::nextRemoteReady_ > remoteReadyQueue_
T exchange(T &obj, U &&new_value)
Finally(G finally, FiberManager &fm)
FibersPoolResizer fibersPoolResizer_
static FiberManager * getFiberManagerUnsafe()
folly::Try< Result > & result_
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
ExceptionCallback exceptionCallback_
void swap(SwapTrackingAlloc< T > &, SwapTrackingAlloc< T > &)
folly::AtomicIntrusiveLinkedList< RemoteTask,&RemoteTask::nextRemoteTask > remoteTaskQueue_
static value_type await(F &&func)
GuardPageAllocator stackAllocator_
FiberManager(const FiberManager &)=delete
folly::Function< void()> immediateFunc_
std::type_index localType_
std::shared_ptr< RequestContext > rcontext
std::unique_ptr< Fiber::LocalData > localData
FiberTailQueue yieldedFibers_
FirstArgOf< F >::type::value_type await(F &&func)