Move OpenSSLPtrTypes.h from folly/io/async/ssl to folly/ssl
[folly.git] / folly / fibers / FiberManagerInternal-inl.h
index b0aa662d629b690d0dce302c19709b01464a53d7..df354aaa4070a9b7933758ea31f83695f08fd639 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -37,8 +37,8 @@ namespace fibers {
 namespace {
 
 inline FiberManager::Options preprocessOptions(FiberManager::Options opts) {
-#ifdef FOLLY_SANITIZE_ADDRESS
-  /* ASAN needs a lot of extra stack space.
+#if defined(FOLLY_SANITIZE_ADDRESS) || defined(UNDEFINED_SANITIZER)
+  /* ASAN/UBSAN needs a lot of extra stack space.
      16x is a conservative estimate, 8x also worked with tests
      where it mattered.  Note that overallocating here does not necessarily
      increase RSS, since unused memory is pretty much free. */
@@ -58,26 +58,48 @@ inline void FiberManager::ensureLoopScheduled() {
   loopController_->schedule();
 }
 
-inline intptr_t FiberManager::activateFiber(Fiber* fiber) {
+inline void FiberManager::activateFiber(Fiber* fiber) {
   DCHECK_EQ(activeFiber_, (Fiber*)nullptr);
 
 #ifdef FOLLY_SANITIZE_ADDRESS
-  registerFiberActivationWithAsan(fiber);
+  DCHECK(!fiber->asanMainStackBase_);
+  DCHECK(!fiber->asanMainStackSize_);
+  auto stack = fiber->getStack();
+  void* asanFakeStack;
+  registerStartSwitchStackWithAsan(&asanFakeStack, stack.first, stack.second);
+  SCOPE_EXIT {
+    registerFinishSwitchStackWithAsan(asanFakeStack, nullptr, nullptr);
+    fiber->asanMainStackBase_ = nullptr;
+    fiber->asanMainStackSize_ = 0;
+  };
 #endif
 
   activeFiber_ = fiber;
-  return jumpContext(&mainContext_, &fiber->fcontext_, fiber->data_);
+  fiber->fiberImpl_.activate();
 }
 
-inline intptr_t FiberManager::deactivateFiber(Fiber* fiber) {
+inline void FiberManager::deactivateFiber(Fiber* fiber) {
   DCHECK_EQ(activeFiber_, fiber);
 
 #ifdef FOLLY_SANITIZE_ADDRESS
-  registerFiberDeactivationWithAsan(fiber);
+  DCHECK(fiber->asanMainStackBase_);
+  DCHECK(fiber->asanMainStackSize_);
+
+  registerStartSwitchStackWithAsan(
+      &fiber->asanFakeStack_,
+      fiber->asanMainStackBase_,
+      fiber->asanMainStackSize_);
+  SCOPE_EXIT {
+    registerFinishSwitchStackWithAsan(
+        fiber->asanFakeStack_,
+        &fiber->asanMainStackBase_,
+        &fiber->asanMainStackSize_);
+    fiber->asanFakeStack_ = nullptr;
+  };
 #endif
 
   activeFiber_ = nullptr;
-  return jumpContext(&fiber->fcontext_, &mainContext_, 0);
+  fiber->fiberImpl_.deactivate();
 }
 
 inline void FiberManager::runReadyFiber(Fiber* fiber) {
@@ -162,7 +184,11 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) {
   }
 }
 
-inline bool FiberManager::loopUntilNoReady() {
+inline void FiberManager::loopUntilNoReady() {
+  return loopController_->runLoop();
+}
+
+inline void FiberManager::loopUntilNoReadyImpl() {
 #ifndef _WIN32
   if (UNLIKELY(!alternateSignalStackRegistered_)) {
     registerAlternateSignalStack();
@@ -206,7 +232,6 @@ inline bool FiberManager::loopUntilNoReady() {
       fiber->rcontext_ = std::move(task->rcontext);
 
       fiber->setFunction(std::move(task->func));
-      fiber->data_ = reinterpret_cast<intptr_t>(fiber);
       if (observer_) {
         observer_->runnable(reinterpret_cast<uintptr_t>(fiber));
       }
@@ -221,8 +246,6 @@ inline bool FiberManager::loopUntilNoReady() {
     }
   }
   readyFibers_.splice(readyFibers_.end(), yieldedFibers_);
-
-  return fibersActive_ > 0;
 }
 
 // We need this to be in a struct, not inlined in addTask, because clang crashes
@@ -276,7 +299,6 @@ void FiberManager::addTask(F&& func) {
     fiber->setFunction(std::ref(*funcLoc));
   }
 
-  fiber->data_ = reinterpret_cast<intptr_t>(fiber);
   readyFibers_.push_back(*fiber);
   if (observer_) {
     observer_->runnable(reinterpret_cast<uintptr_t>(fiber));
@@ -411,7 +433,6 @@ void FiberManager::addTaskFinally(F&& func, G&& finally) {
     fiber->setFunctionFinally(std::ref(*funcLoc), std::ref(*finallyLoc));
   }
 
-  fiber->data_ = reinterpret_cast<intptr_t>(fiber);
   readyFibers_.push_back(*fiber);
   if (observer_) {
     observer_->runnable(reinterpret_cast<uintptr_t>(fiber));