}
inline bool FiberManager::loopUntilNoReady() {
+ if (UNLIKELY(!alternateSignalStackRegistered_)) {
+ registerAlternateSignalStack();
+ }
+
// Support nested FiberManagers
auto originalFiberManager = this;
std::swap(currentFiberManager_, originalFiberManager);
*/
#include "FiberManager.h"
+#include <signal.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <folly/experimental/fibers/Fiber.h>
#include <folly/experimental/fibers/LoopController.h>
+#include <folly/SingletonThreadLocal.h>
+
#ifdef FOLLY_SANITIZE_ADDRESS
#include <dlfcn.h>
}
#endif // FOLLY_SANITIZE_ADDRESS
+
+namespace {
+
+// SIGSTKSZ (8 kB on our architectures) isn't always enough for
+// folly::symbolizer, so allocate 32 kB.
+constexpr size_t kAltStackSize = folly::constexpr_max(SIGSTKSZ, 32 * 1024);
+
+bool hasAlternateStack() {
+ stack_t ss;
+ sigaltstack(nullptr, &ss);
+ return !(ss.ss_flags & SS_DISABLE);
+}
+
+int setAlternateStack(char* sp, size_t size) {
+ CHECK(sp);
+ stack_t ss{};
+ ss.ss_sp = sp;
+ ss.ss_size = size;
+ return sigaltstack(&ss, nullptr);
+}
+
+int unsetAlternateStack() {
+ stack_t ss{};
+ ss.ss_flags = SS_DISABLE;
+ return sigaltstack(&ss, nullptr);
+}
+
+class ScopedAlternateSignalStack {
+ public:
+ ScopedAlternateSignalStack() {
+ if (hasAlternateStack()) {
+ return;
+ }
+
+ stack_ = folly::make_unique<AltStackBuffer>();
+
+ setAlternateStack(stack_->data(), stack_->size());
+ }
+
+ ~ScopedAlternateSignalStack() {
+ if (stack_) {
+ unsetAlternateStack();
+ }
+ }
+
+ private:
+ using AltStackBuffer = std::array<char, kAltStackSize>;
+ std::unique_ptr<AltStackBuffer> stack_;
+};
+}
+
+void FiberManager::registerAlternateSignalStack() {
+ static folly::SingletonThreadLocal<ScopedAlternateSignalStack> singleton;
+ singleton.get();
+
+ alternateSignalStackRegistered_ = true;
+}
}
}
--- /dev/null
+/*
+ * Copyright 2016 Facebook, Inc.
+ *
+ * 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.
+ */
+#include <folly/experimental/fibers/FiberManagerMap.h>
+#include <folly/experimental/symbolizer/SignalHandler.h>
+#include <folly/init/Init.h>
+
+void f(int* p) {
+ // Make sure recursion is not optimized out
+ int a[100];
+ for (size_t i = 0; i < 100; ++i) {
+ a[i] = i;
+ ++(a[i]);
+ if (p) {
+ a[i] += p[i];
+ }
+ }
+ f(a);
+}
+
+int main(int argc, char* argv[]) {
+ folly::init(&argc, &argv);
+
+ folly::EventBase evb;
+ folly::fibers::getFiberManager(evb).addTask([&]() { f(nullptr); });
+ evb.loop();
+}