folly: fixes for use with `-fvisibility-inlines-hidden`
authorAndrew Gallagher <andrewjcg@fb.com>
Tue, 18 Oct 2016 22:50:58 +0000 (15:50 -0700)
committerFacebook Github Bot <facebook-github-bot-bot@fb.com>
Tue, 18 Oct 2016 22:53:46 +0000 (15:53 -0700)
Summary:
- Annotate non-`const` static locals in inline functions which don't require
  a single copy be used globally at runtime.
- Move implmentation from header file to source file (to avoid multiple
  copies at runtime).
- Mark a non-stateful static local as `const` to it easy to ignore when
  searching for problematic static locals.

Reviewed By: yfeldblum

Differential Revision: D4010101

fbshipit-source-id: 3be94a5dc5b7029a26e11b2145c0d41968979a5c

folly/CPortability.h
folly/Malloc.h
folly/Portability.h
folly/Singleton-inl.h
folly/Singleton.h
folly/detail/ThreadLocalDetail.h
folly/io/async/Request.cpp
folly/io/async/Request.h

index 37d97382e56b5d5d88e3759ce645a5d191c34e93..5c497cb2f06492eca0267117cae5292e986a7c2a 100644 (file)
 /* These definitions are in a separate file so that they
  * may be included from C- as well as C++-based projects. */
 
+/**
+ * Portable version check.
+ */
+#ifndef __GNUC_PREREQ
+# if defined __GNUC__ && defined __GNUC_MINOR__
+/* nolint */
+#  define __GNUC_PREREQ(maj, min) ((__GNUC__ << 16) + __GNUC_MINOR__ >= \
+                                   ((maj) << 16) + (min))
+# else
+/* nolint */
+#  define __GNUC_PREREQ(maj, min) 0
+# endif
+#endif
+
 /* Define a convenience macro to test when address sanitizer is being used
  * across the different compilers (e.g. clang, gcc) */
 #if defined(__clang__)
 #else
 # define UBSAN_DISABLE(x)
 #endif // UNDEFINED_SANITIZER
+
+/**
+ * Macro for marking functions as having public visibility.
+ */
+#if defined(__GNUC__)
+# if __GNUC_PREREQ(4, 9)
+#  define FOLLY_EXPORT [[gnu::visibility("default")]]
+# else
+#  define FOLLY_EXPORT __attribute__((__visibility__("default")))
+# endif
+#else
+# define FOLLY_EXPORT
+#endif
index 3aeb765c2cca357f69aa1637beea4fc46cb3fbc5..5ff516bd3c1d11a1a9c648706c1b80614ee7d962 100644 (file)
@@ -179,7 +179,7 @@ FOLLY_MALLOC_NOINLINE inline bool usingJEMalloc() noexcept {
     // Static because otherwise clever compilers will find out that
     // the ptr is not used and does not escape the scope, so they will
     // just optimize away the malloc.
-    static void* ptr = malloc(1);
+    static const void* ptr = malloc(1);
     if (!ptr) {
       // wtf, failing to allocate 1 byte
       return false;
index ff1445224bcda462b5f4a1edb3b9421cc6f3f01e..98ecd0300a31140c49b0c37a9951b484c7fcac69 100644 (file)
@@ -167,18 +167,6 @@ constexpr bool kHasUnalignedAccess = false;
 # define FOLLY_MSVC_DISABLE_WARNING(warningNumber)
 #endif
 
-// portable version check
-#ifndef __GNUC_PREREQ
-# if defined __GNUC__ && defined __GNUC_MINOR__
-/* nolint */
-#  define __GNUC_PREREQ(maj, min) ((__GNUC__ << 16) + __GNUC_MINOR__ >= \
-                                   ((maj) << 16) + (min))
-# else
-/* nolint */
-#  define __GNUC_PREREQ(maj, min) 0
-# endif
-#endif
-
 #if defined(__GNUC__) && !defined(__APPLE__) && !__GNUC_PREREQ(4,9)
 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56019
 // gcc 4.8.x incorrectly placed max_align_t in the root namespace
index dad943be7184b09011326bf20cbc6fdade669873..19ed5c528a3184b8f3710c686fd4b89f6ddddee4 100644 (file)
@@ -21,7 +21,7 @@ namespace detail {
 template <typename T>
 template <typename Tag, typename VaultTag>
 SingletonHolder<T>& SingletonHolder<T>::singleton() {
-  static auto entry =
+  /* library-local */ static auto entry =
       createGlobal<SingletonHolder<T>, std::pair<Tag, VaultTag>>([]() {
         return new SingletonHolder<T>({typeid(T), typeid(Tag)},
                                       *SingletonVault::singleton<VaultTag>());
index 0539e28055e294a05bbd18d167a69cbe071e5dc3..c4640aff40d5b4e41b54f37302ce1e5284e7bed5 100644 (file)
@@ -434,7 +434,7 @@ class SingletonVault {
   // tests only.
   template <typename VaultTag = detail::DefaultTag>
   static SingletonVault* singleton() {
-    static SingletonVault* vault =
+    /* library-local */ static auto vault =
         detail::createGlobal<SingletonVault, VaultTag>();
     return vault;
   }
@@ -442,9 +442,8 @@ class SingletonVault {
   typedef std::string(*StackTraceGetterPtr)();
 
   static std::atomic<StackTraceGetterPtr>& stackTraceGetter() {
-    static std::atomic<StackTraceGetterPtr>* stackTraceGetterPtr =
-        detail::createGlobal<std::atomic<StackTraceGetterPtr>,
-                             SingletonVault>();
+    /* library-local */ static auto stackTraceGetterPtr = detail::
+        createGlobal<std::atomic<StackTraceGetterPtr>, SingletonVault>();
     return *stackTraceGetterPtr;
   }
 
@@ -657,7 +656,7 @@ class LeakySingleton {
   };
 
   static Entry& entryInstance() {
-    static auto entry = detail::createGlobal<Entry, Tag>();
+    /* library-local */ static auto entry = detail::createGlobal<Entry, Tag>();
     return *entry;
   }
 
index fcd1a90f57c5ea0ce76be84b94d6849b9d074f72..c04fee1eb95e53213d853b4a8fb24f26ec2021cd 100644 (file)
@@ -325,7 +325,7 @@ struct StaticMeta : StaticMetaBase {
   static StaticMeta<Tag, AccessMode>& instance() {
     // Leak it on exit, there's only one per process and we don't have to
     // worry about synchronization with exiting threads.
-    static auto instance =
+    /* library-local */ static auto instance =
         detail::createGlobal<StaticMeta<Tag, AccessMode>, void>();
     return *instance;
   }
index 8d44a5568a64d551adac4a704ce180ff8465b982..3babeea69bad670f7e8597e23ba3aeff733377a3 100644 (file)
@@ -112,4 +112,13 @@ std::shared_ptr<RequestContext>& RequestContext::getStaticContext() {
 
   return singleton.get();
 }
+
+RequestContext* RequestContext::get() {
+  auto context = getStaticContext();
+  if (!context) {
+    static RequestContext defaultContext;
+    return std::addressof(defaultContext);
+  }
+  return context.get();
+}
 }
index 48252a2fe9e24dbc0ee9abc5677f5074fc13bf8c..59d66f94fce53bacb9ba9c6e38173eccb5824dc4 100644 (file)
@@ -53,14 +53,7 @@ class RequestContext {
   }
 
   // Get the current context.
-  static RequestContext* get() {
-    auto context = getStaticContext();
-    if (!context) {
-      static RequestContext defaultContext;
-      return std::addressof(defaultContext);
-    }
-    return context.get();
-  }
+  static RequestContext* get();
 
   // The following API may be used to set per-request data in a thread-safe way.
   // This access is still performance sensitive, so please ask if you need help