2017
[folly.git] / folly / test / ThreadLocalTest.cpp
index aaa3794d452ab0f1523450a14219600a51a403b9..52fef3f8d172d1336c9579ce035211f9f9be3673 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.
 
 #include <folly/ThreadLocal.h>
 
+#ifndef _WIN32
 #include <dlfcn.h>
-#include <sys/types.h>
 #include <sys/wait.h>
+#endif
+
+#include <sys/types.h>
 
 #include <array>
 #include <atomic>
 #include <unordered_map>
 
 #include <glog/logging.h>
-#include <gtest/gtest.h>
 
 #include <folly/Baton.h>
 #include <folly/Memory.h>
+#include <folly/ThreadId.h>
 #include <folly/experimental/io/FsUtil.h>
+#include <folly/portability/GTest.h>
 #include <folly/portability/Unistd.h>
 
 using namespace folly;
@@ -402,7 +406,7 @@ class FillObject {
 
  private:
   uint64_t val() const {
-    return (idx_ << 40) | uint64_t(pthread_self());
+    return (idx_ << 40) | folly::getCurrentThreadID();
   }
 
   uint64_t idx_;
@@ -413,16 +417,16 @@ class FillObject {
 
 #if FOLLY_HAVE_STD_THIS_THREAD_SLEEP_FOR
 TEST(ThreadLocal, Stress) {
-  constexpr size_t numFillObjects = 250;
+  static constexpr size_t numFillObjects = 250;
   std::array<ThreadLocalPtr<FillObject>, numFillObjects> objects;
 
-  constexpr size_t numThreads = 32;
-  constexpr size_t numReps = 20;
+  static constexpr size_t numThreads = 32;
+  static constexpr size_t numReps = 20;
 
   std::vector<std::thread> threads;
   threads.reserve(numThreads);
 
-  for (size_t i = 0; i < numThreads; ++i) {
+  for (size_t k = 0; k < numThreads; ++k) {
     threads.emplace_back([&objects] {
       for (size_t rep = 0; rep < numReps; ++rep) {
         for (size_t i = 0; i < objects.size(); ++i) {
@@ -543,6 +547,7 @@ TEST(ThreadLocal, Fork) {
 }
 #endif
 
+#ifndef _WIN32
 struct HoldsOneTag2 {};
 
 TEST(ThreadLocal, Fork2) {
@@ -572,9 +577,15 @@ TEST(ThreadLocal, Fork2) {
   }
 }
 
+// Elide this test when using any sanitizer. Otherwise, the dlopen'ed code
+// would end up running without e.g., ASAN-initialized data structures and
+// failing right away.
+#if !defined FOLLY_SANITIZE_ADDRESS && !defined UNDEFINED_SANITIZER && \
+    !defined FOLLY_SANITIZE_THREAD
+
 TEST(ThreadLocal, SharedLibrary) {
   auto exe = fs::executable_path();
-  auto lib = exe.parent_path() / "lib_thread_local_test.so";
+  auto lib = exe.parent_path() / "thread_local_test_lib.so";
   auto handle = dlopen(lib.string().c_str(), RTLD_LAZY);
   EXPECT_NE(nullptr, handle);
 
@@ -613,6 +624,9 @@ TEST(ThreadLocal, SharedLibrary) {
   t2.join();
 }
 
+#endif
+#endif
+
 namespace folly { namespace threadlocal_detail {
 struct PthreadKeyUnregisterTester {
   PthreadKeyUnregister p;