unioil-loyalty-rn-app/ios/Pods/Flipper-Folly/folly/fibers/SimpleLoopController.h

120 lines
3.1 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <atomic>
#include <folly/Function.h>
#include <folly/Likely.h>
#include <folly/fibers/FiberManager.h>
#include <folly/fibers/LoopController.h>
namespace folly {
namespace fibers {
class FiberManager;
class SimpleLoopController : public LoopController {
public:
SimpleLoopController();
~SimpleLoopController();
/**
* Run FiberManager loop; if no ready task are present,
* run provided function. Stops after both stop() has been called
* and no waiting tasks remain.
*/
template <typename F>
void loop(F&& func) {
loopThread_.store(std::this_thread::get_id(), std::memory_order_release);
bool waiting = false;
stopRequested_ = false;
while (LIKELY(waiting || !stopRequested_)) {
func();
runTimeouts();
if (scheduled_) {
scheduled_ = false;
runLoop();
waiting = fm_->hasTasks();
}
}
loopThread_.store({}, std::memory_order_release);
}
/**
* Requests exit from loop() as soon as all waiting tasks complete.
*/
void stop() { stopRequested_ = true; }
int remoteScheduleCalled() const { return remoteScheduleCalled_; }
void runLoop() override {
do {
if (remoteLoopRun_ < remoteScheduleCalled_) {
for (; remoteLoopRun_ < remoteScheduleCalled_; ++remoteLoopRun_) {
if (fm_->shouldRunLoopRemote()) {
fm_->loopUntilNoReadyImpl();
}
}
} else {
fm_->loopUntilNoReadyImpl();
}
} while (remoteLoopRun_ < remoteScheduleCalled_);
}
void runEagerFiber(Fiber* fiber) override { fm_->runEagerFiberImpl(fiber); }
void schedule() override { scheduled_ = true; }
HHWheelTimer* timer() override { return timer_.get(); }
bool isInLoopThread() const {
auto tid = loopThread_.load(std::memory_order_relaxed);
return tid == std::thread::id() || tid == std::this_thread::get_id();
}
private:
FiberManager* fm_;
std::atomic<bool> scheduled_{false};
bool stopRequested_;
std::atomic<int> remoteScheduleCalled_{0};
int remoteLoopRun_{0};
std::atomic<std::thread::id> loopThread_;
class SimpleTimeoutManager;
std::unique_ptr<SimpleTimeoutManager> timeoutManager_;
std::shared_ptr<HHWheelTimer> timer_;
/* LoopController interface */
void setFiberManager(FiberManager* fm) override { fm_ = fm; }
void scheduleThreadSafe() override {
++remoteScheduleCalled_;
scheduled_ = true;
}
void runTimeouts();
friend class FiberManager;
};
} // namespace fibers
} // namespace folly