Unbreak folly on x86-32
[folly.git] / folly / ScopeGuard.h
index 3822e4d130d777f81edb060d5df583ee4bc21581..a8c269147a068ae948d56cf155244f05d3ad250a 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.
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef FOLLY_SCOPEGUARD_H_
-#define FOLLY_SCOPEGUARD_H_
+#pragma once
 
 #include <cstddef>
 #include <functional>
@@ -23,6 +22,7 @@
 #include <type_traits>
 #include <utility>
 
+#include <folly/Portability.h>
 #include <folly/Preprocessor.h>
 #include <folly/detail/UncaughtExceptionCounter.h>
 
@@ -38,7 +38,8 @@ namespace folly {
  * a functor, or a void(*)() function pointer.
  *
  *
- * Usage example: Add a friend to memory iff it is also added to the db.
+ * Usage example: Add a friend to memory if and only if it is also added
+ * to the db.
  *
  * void User::addFriend(User& newFriend) {
  *   // add the friend to memory
@@ -75,6 +76,17 @@ class ScopeGuardImplBase {
     dismissed_ = true;
   }
 
+  template <typename T>
+  FOLLY_ALWAYS_INLINE static void runAndWarnAboutToCrashOnException(
+      T& function) noexcept {
+    try {
+      function();
+    } catch (...) {
+      warnAboutToCrash();
+      std::terminate();
+    }
+  }
+
  protected:
   ScopeGuardImplBase() noexcept : dismissed_(false) {}
 
@@ -88,6 +100,9 @@ class ScopeGuardImplBase {
   }
 
   bool dismissed_;
+
+ private:
+  static void warnAboutToCrash() noexcept;
 };
 
 template <typename FunctionType>
@@ -151,7 +166,9 @@ class ScopeGuardImpl : public ScopeGuardImplBase {
 
   void* operator new(std::size_t) = delete;
 
-  void execute() noexcept { function_(); }
+  void execute() noexcept {
+    runAndWarnAboutToCrashOnException(function_);
+  }
 
   FunctionType function_;
 };
@@ -173,7 +190,8 @@ typedef ScopeGuardImplBase&& ScopeGuard;
 namespace detail {
 
 #if defined(FOLLY_EXCEPTION_COUNT_USE_CXA_GET_GLOBALS) || \
-    defined(FOLLY_EXCEPTION_COUNT_USE_GETPTD)
+    defined(FOLLY_EXCEPTION_COUNT_USE_GETPTD) ||          \
+    defined(FOLLY_EXCEPTION_COUNT_USE_STD)
 
 /**
  * ScopeGuard used for executing a function when leaving the current scope
@@ -184,7 +202,7 @@ namespace detail {
  * If the parameter is false, then the function is executed if no new uncaught
  * exceptions are present at the end of the scope.
  *
- * Used to implement SCOPE_FAIL and SCOPE_SUCCES below.
+ * Used to implement SCOPE_FAIL and SCOPE_SUCCESS below.
  */
 template <typename FunctionType, bool executeOnException>
 class ScopeGuardForNewException {
@@ -204,7 +222,11 @@ class ScopeGuardForNewException {
 
   ~ScopeGuardForNewException() noexcept(executeOnException) {
     if (executeOnException == exceptionCounter_.isNewUncaughtException()) {
-      function_();
+      if (executeOnException) {
+        ScopeGuardImplBase::runAndWarnAboutToCrashOnException(function_);
+      } else {
+        function_();
+      }
     }
   }
 
@@ -258,14 +280,15 @@ operator+(detail::ScopeGuardOnExit, FunctionType&& fn) {
 }
 } // namespace detail
 
-} // folly
+} // namespace folly
 
 #define SCOPE_EXIT \
   auto FB_ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE) \
   = ::folly::detail::ScopeGuardOnExit() + [&]() noexcept
 
 #if defined(FOLLY_EXCEPTION_COUNT_USE_CXA_GET_GLOBALS) || \
-    defined(FOLLY_EXCEPTION_COUNT_USE_GETPTD)
+    defined(FOLLY_EXCEPTION_COUNT_USE_GETPTD) ||          \
+    defined(FOLLY_EXCEPTION_COUNT_USE_STD)
 #define SCOPE_FAIL \
   auto FB_ANONYMOUS_VARIABLE(SCOPE_FAIL_STATE) \
   = ::folly::detail::ScopeGuardOnFail() + [&]() noexcept
@@ -274,5 +297,3 @@ operator+(detail::ScopeGuardOnExit, FunctionType&& fn) {
   auto FB_ANONYMOUS_VARIABLE(SCOPE_SUCCESS_STATE) \
   = ::folly::detail::ScopeGuardOnSuccess() + [&]()
 #endif // native uncaught_exception() supported
-
-#endif // FOLLY_SCOPEGUARD_H_