// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/threading/thread_local_storage.h"

#if defined(OS_WIN)
#include <windows.h>
#include <process.h>
#endif

#include "base/macros.h"
#include "base/no_destructor.h"
#include "base/threading/simple_thread.h"
#include "build_config.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(OS_WIN)
// Ignore warnings about ptr->int conversions that we use when
// storing ints into ThreadLocalStorage.
#pragma warning(disable : 4311 4312)
#endif

namespace base {

#if defined(OS_POSIX)

namespace internal {

// This class is friended by ThreadLocalStorage.
class ThreadLocalStorageTestInternal {
 public:
  static bool HasBeenDestroyed() {
    return ThreadLocalStorage::HasBeenDestroyed();
  }
};

}  // namespace internal

#endif  // defined(OS_POSIX)

namespace {

const int kInitialTlsValue = 0x5555;
const int kFinalTlsValue = 0x7777;
// How many times must a destructor be called before we really are done.
const int kNumberDestructorCallRepetitions = 3;

void ThreadLocalStorageCleanup(void* value);

ThreadLocalStorage::Slot& TLSSlot() {
  static NoDestructor<ThreadLocalStorage::Slot> slot(
      &ThreadLocalStorageCleanup);
  return *slot;
}

class ThreadLocalStorageRunner : public DelegateSimpleThread::Delegate {
 public:
  explicit ThreadLocalStorageRunner(int* tls_value_ptr)
      : tls_value_ptr_(tls_value_ptr) {}

  ~ThreadLocalStorageRunner() override = default;

  void Run() override {
    *tls_value_ptr_ = kInitialTlsValue;
    TLSSlot().Set(tls_value_ptr_);

    int* ptr = static_cast<int*>(TLSSlot().Get());
    EXPECT_EQ(ptr, tls_value_ptr_);
    EXPECT_EQ(*ptr, kInitialTlsValue);
    *tls_value_ptr_ = 0;

    ptr = static_cast<int*>(TLSSlot().Get());
    EXPECT_EQ(ptr, tls_value_ptr_);
    EXPECT_EQ(*ptr, 0);

    *ptr = kFinalTlsValue + kNumberDestructorCallRepetitions;
  }

 private:
  int* tls_value_ptr_;
  DISALLOW_COPY_AND_ASSIGN(ThreadLocalStorageRunner);
};


void ThreadLocalStorageCleanup(void *value) {
  int *ptr = reinterpret_cast<int*>(value);
  // Destructors should never be called with a NULL.
  ASSERT_NE(reinterpret_cast<int*>(NULL), ptr);
  if (*ptr == kFinalTlsValue)
    return;  // We've been called enough times.
  ASSERT_LT(kFinalTlsValue, *ptr);
  ASSERT_GE(kFinalTlsValue + kNumberDestructorCallRepetitions, *ptr);
  --*ptr;  // Move closer to our target.
  // Tell tls that we're not done with this thread, and still need destruction.
  TLSSlot().Set(value);
}

#if defined(OS_POSIX)
constexpr intptr_t kDummyValue = 0xABCD;
constexpr size_t kKeyCount = 20;

// The order in which pthread keys are destructed is not specified by the POSIX
// specification. Hopefully, of the 20 keys we create, some of them should be
// destroyed after the TLS key is destroyed.
class UseTLSDuringDestructionRunner {
 public:
  UseTLSDuringDestructionRunner() = default;

  // The order in which pthread_key destructors are called is not well defined.
  // Hopefully, by creating 10 both before and after initializing TLS on the
  // thread, at least 1 will be called after TLS destruction.
  void Run() {
    ASSERT_FALSE(internal::ThreadLocalStorageTestInternal::HasBeenDestroyed());

    // Create 10 pthread keys before initializing TLS on the thread.
    size_t slot_index = 0;
    for (; slot_index < 10; ++slot_index) {
      CreateTlsKeyWithDestructor(slot_index);
    }

    // Initialize the Chrome TLS system. It's possible that base::Thread has
    // already initialized Chrome TLS, but we don't rely on that.
    slot_.Set(reinterpret_cast<void*>(kDummyValue));

    // Create 10 pthread keys after initializing TLS on the thread.
    for (; slot_index < kKeyCount; ++slot_index) {
      CreateTlsKeyWithDestructor(slot_index);
    }
  }

  bool teardown_works_correctly() { return teardown_works_correctly_; }

 private:
  struct TLSState {
    pthread_key_t key;
    bool* teardown_works_correctly;
  };

  // The POSIX TLS destruction API takes as input a single C-function, which is
  // called with the current |value| of a (key, value) pair. We need this
  // function to do two things: set the |value| to nullptr, which requires
  // knowing the associated |key|, and update the |teardown_works_correctly_|
  // state.
  //
  // To accomplish this, we set the value to an instance of TLSState, which
  // contains |key| as well as a pointer to |teardown_works_correctly|.
  static void ThreadLocalDestructor(void* value) {
    TLSState* state = static_cast<TLSState*>(value);
    int result = pthread_setspecific(state->key, nullptr);
    ASSERT_EQ(result, 0);

    // If this path is hit, then the thread local destructor was called after
    // the Chrome-TLS destructor and the internal state was updated correctly.
    // No further checks are necessary.
    if (internal::ThreadLocalStorageTestInternal::HasBeenDestroyed()) {
      *(state->teardown_works_correctly) = true;
      return;
    }

    // If this path is hit, then the thread local destructor was called before
    // the Chrome-TLS destructor is hit. The ThreadLocalStorage::Slot should
    // still function correctly.
    ASSERT_EQ(reinterpret_cast<intptr_t>(slot_.Get()), kDummyValue);
  }

  void CreateTlsKeyWithDestructor(size_t index) {
    ASSERT_LT(index, kKeyCount);

    tls_states_[index].teardown_works_correctly = &teardown_works_correctly_;
    int result = pthread_key_create(
        &(tls_states_[index].key),
        UseTLSDuringDestructionRunner::ThreadLocalDestructor);
    ASSERT_EQ(result, 0);

    result = pthread_setspecific(tls_states_[index].key, &tls_states_[index]);
    ASSERT_EQ(result, 0);
  }

  static base::ThreadLocalStorage::Slot slot_;
  bool teardown_works_correctly_ = false;
  TLSState tls_states_[kKeyCount];

  DISALLOW_COPY_AND_ASSIGN(UseTLSDuringDestructionRunner);
};

base::ThreadLocalStorage::Slot UseTLSDuringDestructionRunner::slot_;

void* UseTLSTestThreadRun(void* input) {
  UseTLSDuringDestructionRunner* runner =
      static_cast<UseTLSDuringDestructionRunner*>(input);
  runner->Run();
  return nullptr;
}

#endif  // defined(OS_POSIX)

}  // namespace

TEST(ThreadLocalStorageTest, Basics) {
  ThreadLocalStorage::Slot slot;
  slot.Set(reinterpret_cast<void*>(123));
  int value = reinterpret_cast<intptr_t>(slot.Get());
  EXPECT_EQ(value, 123);
}

#if defined(THREAD_SANITIZER) || \
    (defined(OS_WIN) && defined(ARCH_CPU_X86_64) && !defined(NDEBUG))
// Do not run the test under ThreadSanitizer. Because this test iterates its
// own TSD destructor for the maximum possible number of times, TSan can't jump
// in after the last destructor invocation, therefore the destructor remains
// unsynchronized with the following users of the same TSD slot. This results
// in race reports between the destructor and functions in other tests.
//
// It is disabled on Win x64 with incremental linking (i.e. "Debug") pending
// resolution of http://crbug.com/251251.
#define MAYBE_TLSDestructors DISABLED_TLSDestructors
#else
#define MAYBE_TLSDestructors TLSDestructors
#endif
TEST(ThreadLocalStorageTest, MAYBE_TLSDestructors) {
  // Create a TLS index with a destructor.  Create a set of
  // threads that set the TLS, while the destructor cleans it up.
  // After the threads finish, verify that the value is cleaned up.
  const int kNumThreads = 5;
  int values[kNumThreads];
  ThreadLocalStorageRunner* thread_delegates[kNumThreads];
  DelegateSimpleThread* threads[kNumThreads];

  // Spawn the threads.
  for (int index = 0; index < kNumThreads; index++) {
    values[index] = kInitialTlsValue;
    thread_delegates[index] = new ThreadLocalStorageRunner(&values[index]);
    threads[index] = new DelegateSimpleThread(thread_delegates[index],
                                              "tls thread");
    threads[index]->Start();
  }

  // Wait for the threads to finish.
  for (int index = 0; index < kNumThreads; index++) {
    threads[index]->Join();
    delete threads[index];
    delete thread_delegates[index];

    // Verify that the destructor was called and that we reset.
    EXPECT_EQ(values[index], kFinalTlsValue);
  }
}

TEST(ThreadLocalStorageTest, TLSReclaim) {
  // Creates and destroys many TLS slots and ensures they all zero-inited.
  for (int i = 0; i < 1000; ++i) {
    ThreadLocalStorage::Slot slot(nullptr);
    EXPECT_EQ(nullptr, slot.Get());
    slot.Set(reinterpret_cast<void*>(0xBAADF00D));
    EXPECT_EQ(reinterpret_cast<void*>(0xBAADF00D), slot.Get());
  }
}

#if defined(OS_POSIX)
// Unlike POSIX, Windows does not iterate through the OS TLS to cleanup any
// values there. Instead a per-module thread destruction function is called.
// However, it is not possible to perform a check after this point (as the code
// is detached from the thread), so this check remains POSIX only.
TEST(ThreadLocalStorageTest, UseTLSDuringDestruction) {
  UseTLSDuringDestructionRunner runner;
  pthread_t thread;
  int result = pthread_create(&thread, nullptr, UseTLSTestThreadRun, &runner);
  ASSERT_EQ(result, 0);

  result = pthread_join(thread, nullptr);
  ASSERT_EQ(result, 0);

  EXPECT_TRUE(runner.teardown_works_correctly());
}
#endif  // defined(OS_POSIX)

}  // namespace base
