return &userBuffer_;
}
-template <typename G>
-void Fiber::setReadyFunction(G&& func) {
- assert(state_ == INVALID || state_ == NOT_STARTED);
- readyFunc_ = std::move(func);
-}
-
template <typename T>
T& Fiber::LocalData::get() {
if (data_) {
template <typename F, typename G>
void setFunctionFinally(F&& func, G&& finally);
- template <typename G>
- void setReadyFunction(G&& func);
-
static void fiberFuncHelper(intptr_t fiber);
void fiberFunc();
FContext fcontext_; /**< current task execution context */
intptr_t data_; /**< Used to keep some data with the Fiber */
std::function<void()> func_; /**< task function */
- std::function<void()> readyFunc_; /**< function to be executed before jumping
- to this fiber */
/**
* Points to next fiber in remote ready list
while (fiber->state_ == Fiber::NOT_STARTED ||
fiber->state_ == Fiber::READY_TO_RUN) {
activeFiber_ = fiber;
- if (fiber->readyFunc_) {
- fiber->readyFunc_();
- }
jumpContext(&mainContext_, &fiber->fcontext_, fiber->data_);
if (fiber->state_ == Fiber::AWAITING_IMMEDIATE) {
try {
ensureLoopScheduled();
}
-template <typename F, typename G>
-void FiberManager::addTaskReadyFunc(F&& func, G&& readyFunc) {
- auto fiber = getFiber();
- if (currentFiber_) {
- fiber->localData_ = currentFiber_->localData_;
- }
-
- fiber->setFunction(std::forward<F>(func));
- fiber->setReadyFunction(std::forward<G>(readyFunc));
-
- fiber->data_ = reinterpret_cast<intptr_t>(fiber);
- readyFibers_.push_back(*fiber);
-
- ensureLoopScheduled();
-}
-
template <typename F>
void FiberManager::addTaskRemote(F&& func) {
auto task = [&]() {
template <typename T>
T& FiberManager::local() {
- assert(getFiberManager().currentFiber_ != nullptr);
- return currentFiber_->localData_.get<T>();
+ if (currentFiber_) {
+ return currentFiber_->localData_.get<T>();
+ }
+ return localThread<T>();
+}
+
+template <typename T>
+T& FiberManager::localThread() {
+ static thread_local T t;
+ return t;
}
template <typename F>
template <typename F>
void addTask(F&& func);
- /**
- * Add a new task to be executed, along with a function readyFunc_ which needs
- * to be executed just before jumping to the ready fiber
- *
- * @param func Task functor; must have a signature of `T func()` for some T.
- * @param readyFunc functor that needs to be executed just before jumping to
- * ready fiber on the main context. This can for example be
- * used to set up state before starting or resuming a fiber.
- */
- template <typename F, typename G>
- void addTaskReadyFunc(F&& func, G&& readyFunc);
-
/**
* Add a new task to be executed. Safe to call from other threads.
*
template <typename T>
T& local();
+ template <typename T>
+ static T& localThread();
+
/**
* @return How many fiber objects (and stacks) has this manager allocated.
*/
*/
template <typename T>
T& local() {
- return FiberManager::getFiberManager().local<T>();
+ auto fm = FiberManager::getFiberManagerUnsafe();
+ if (fm) {
+ return fm->local<T>();
+ }
+ return FiberManager::localThread<T>();
}
}}