/* 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
// 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;
# 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
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>());
// tests only.
template <typename VaultTag = detail::DefaultTag>
static SingletonVault* singleton() {
- static SingletonVault* vault =
+ /* library-local */ static auto vault =
detail::createGlobal<SingletonVault, VaultTag>();
return vault;
}
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;
}
};
static Entry& entryInstance() {
- static auto entry = detail::createGlobal<Entry, Tag>();
+ /* library-local */ static auto entry = detail::createGlobal<Entry, Tag>();
return *entry;
}
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;
}
return singleton.get();
}
+
+RequestContext* RequestContext::get() {
+ auto context = getStaticContext();
+ if (!context) {
+ static RequestContext defaultContext;
+ return std::addressof(defaultContext);
+ }
+ return context.get();
+}
}
}
// 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