chromium/base/threading/thread_local_storage_unittest.cc

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

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
#pragma allow_unsafe_buffers
#endif

#include "base/threading/thread_local_storage.h"

#include "base/memory/raw_ptr.h"
#include "base/no_destructor.h"
#include "base/threading/simple_thread.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"

#if BUILDFLAG(IS_WIN)
#include <windows.h>

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

namespace base {

#if BUILDFLAG(IS_POSIX)

namespace internal {

// This class is friended by ThreadLocalStorage.
class ThreadLocalStorageTestInternal {};

}  // namespace internal

#endif  // BUILDFLAG(IS_POSIX)

namespace {

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

void ThreadLocalStorageCleanup(void* value);

ThreadLocalStorage::Slot& TLSSlot() {}

class ThreadLocalStorageRunner : public DelegateSimpleThread::Delegate {};


void ThreadLocalStorageCleanup(void *value) {}

#if BUILDFLAG(IS_POSIX)
constexpr intptr_t kDummyValue =;
constexpr size_t kKeyCount =;

// 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 {};

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

void* UseTLSTestThreadRun(void* input) {}

#endif  // BUILDFLAG(IS_POSIX)

class TlsDestructionOrderRunner : public DelegateSimpleThread::Delegate {};
std::vector<int> TlsDestructionOrderRunner::destructor_calls;

class CreateDuringDestructionRunner : public DelegateSimpleThread::Delegate {};
bool CreateDuringDestructionRunner::second_destructor_called =;

}  // namespace

TEST(ThreadLocalStorageTest, Basics) {}

#if defined(THREAD_SANITIZER)
// 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.
#define MAYBE_TLSDestructors
#else
#define MAYBE_TLSDestructors
#endif
TEST(ThreadLocalStorageTest, MAYBE_TLSDestructors) {}

TEST(ThreadLocalStorageTest, TLSReclaim) {}

#if BUILDFLAG(IS_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) {}
#endif  // BUILDFLAG(IS_POSIX)

// Test that TLS slots are destroyed in the reverse order: the one that was
// created first is destroyed last.
TEST(ThreadLocalStorageTest, DestructionOrder) {}

TEST(ThreadLocalStorageTest, CreateDuringDestruction) {}

}  // namespace base