diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /security/sandbox/chromium/base/threading/thread_local_storage.h | |
parent | Initial commit. (diff) | |
download | thunderbird-upstream.tar.xz thunderbird-upstream.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'security/sandbox/chromium/base/threading/thread_local_storage.h')
-rw-r--r-- | security/sandbox/chromium/base/threading/thread_local_storage.h | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/security/sandbox/chromium/base/threading/thread_local_storage.h b/security/sandbox/chromium/base/threading/thread_local_storage.h new file mode 100644 index 0000000000..73b845ef56 --- /dev/null +++ b/security/sandbox/chromium/base/threading/thread_local_storage.h @@ -0,0 +1,175 @@ +// 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. + +#ifndef BASE_THREADING_THREAD_LOCAL_STORAGE_H_ +#define BASE_THREADING_THREAD_LOCAL_STORAGE_H_ + +#include <stdint.h> + +#include "base/atomicops.h" +#include "base/base_export.h" +#include "base/macros.h" +#include "build/build_config.h" + +#if defined(OS_WIN) +#include "base/win/windows_types.h" +#elif defined(OS_POSIX) || defined(OS_FUCHSIA) +#include <pthread.h> +#endif + +namespace ui { +class TLSDestructionCheckerForX11; +} + +namespace base { + +class SamplingHeapProfiler; + +namespace debug { +class GlobalActivityTracker; +} // namespace debug + +namespace trace_event { +class MallocDumpProvider; +} // namespace trace_event + +namespace internal { + +class ThreadLocalStorageTestInternal; + +// WARNING: You should *NOT* use this class directly. +// PlatformThreadLocalStorage is a low-level abstraction of the OS's TLS +// interface. Instead, you should use one of the following: +// * ThreadLocalBoolean (from thread_local.h) for booleans. +// * ThreadLocalPointer (from thread_local.h) for pointers. +// * ThreadLocalStorage::StaticSlot/Slot for more direct control of the slot. +class BASE_EXPORT PlatformThreadLocalStorage { + public: + +#if defined(OS_WIN) + typedef unsigned long TLSKey; + enum : unsigned { TLS_KEY_OUT_OF_INDEXES = TLS_OUT_OF_INDEXES }; +#elif defined(OS_POSIX) || defined(OS_FUCHSIA) + typedef pthread_key_t TLSKey; + // The following is a "reserved key" which is used in our generic Chromium + // ThreadLocalStorage implementation. We expect that an OS will not return + // such a key, but if it is returned (i.e., the OS tries to allocate it) we + // will just request another key. + enum { TLS_KEY_OUT_OF_INDEXES = 0x7FFFFFFF }; +#endif + + // The following methods need to be supported on each OS platform, so that + // the Chromium ThreadLocalStore functionality can be constructed. + // Chromium will use these methods to acquire a single OS slot, and then use + // that to support a much larger number of Chromium slots (independent of the + // OS restrictions). + // The following returns true if it successfully is able to return an OS + // key in |key|. + static bool AllocTLS(TLSKey* key); + // Note: FreeTLS() doesn't have to be called, it is fine with this leak, OS + // might not reuse released slot, you might just reset the TLS value with + // SetTLSValue(). + static void FreeTLS(TLSKey key); + static void SetTLSValue(TLSKey key, void* value); + static void* GetTLSValue(TLSKey key) { +#if defined(OS_WIN) + return TlsGetValue(key); +#elif defined(OS_POSIX) || defined(OS_FUCHSIA) + return pthread_getspecific(key); +#endif + } + + // Each platform (OS implementation) is required to call this method on each + // terminating thread when the thread is about to terminate. This method + // will then call all registered destructors for slots in Chromium + // ThreadLocalStorage, until there are no slot values remaining as having + // been set on this thread. + // Destructors may end up being called multiple times on a terminating + // thread, as other destructors may re-set slots that were previously + // destroyed. +#if defined(OS_WIN) + // Since Windows which doesn't support TLS destructor, the implementation + // should use GetTLSValue() to retrieve the value of TLS slot. + static void OnThreadExit(); +#elif defined(OS_POSIX) || defined(OS_FUCHSIA) + // |Value| is the data stored in TLS slot, The implementation can't use + // GetTLSValue() to retrieve the value of slot as it has already been reset + // in Posix. + static void OnThreadExit(void* value); +#endif +}; + +} // namespace internal + +// Wrapper for thread local storage. This class doesn't do much except provide +// an API for portability. +class BASE_EXPORT ThreadLocalStorage { + public: + // Prototype for the TLS destructor function, which can be optionally used to + // cleanup thread local storage on thread exit. 'value' is the data that is + // stored in thread local storage. + typedef void (*TLSDestructorFunc)(void* value); + + // A key representing one value stored in TLS. Use as a class member or a + // local variable. If you need a static storage duration variable, use the + // following pattern with a NoDestructor<Slot>: + // void MyDestructorFunc(void* value); + // ThreadLocalStorage::Slot& ImportantContentTLS() { + // static NoDestructor<ThreadLocalStorage::Slot> important_content_tls( + // &MyDestructorFunc); + // return *important_content_tls; + // } + class BASE_EXPORT Slot final { + public: + // |destructor| is a pointer to a function to perform per-thread cleanup of + // this object. If set to nullptr, no cleanup is done for this TLS slot. + explicit Slot(TLSDestructorFunc destructor = nullptr); + // If a destructor was set for this slot, removes the destructor so that + // remaining threads exiting will not free data. + ~Slot(); + + // Get the thread-local value stored in slot 'slot'. + // Values are guaranteed to initially be zero. + void* Get() const; + + // Set the thread-local value stored in slot 'slot' to + // value 'value'. + void Set(void* value); + + private: + void Initialize(TLSDestructorFunc destructor); + void Free(); + + static constexpr int kInvalidSlotValue = -1; + int slot_ = kInvalidSlotValue; + uint32_t version_ = 0; + + DISALLOW_COPY_AND_ASSIGN(Slot); + }; + + private: + // In most cases, most callers should not need access to HasBeenDestroyed(). + // If you are working in code that runs during thread destruction, contact the + // base OWNERs for advice and then make a friend request. + // + // Returns |true| if Chrome's implementation of TLS is being or has been + // destroyed during thread destruction. Attempting to call Slot::Get() during + // destruction is disallowed and will hit a DCHECK. Any code that relies on + // TLS during thread destruction must first check this method before calling + // Slot::Get(). + friend class SequenceCheckerImpl; + friend class SamplingHeapProfiler; + friend class ThreadCheckerImpl; + friend class internal::ThreadLocalStorageTestInternal; + friend class trace_event::MallocDumpProvider; + friend class debug::GlobalActivityTracker; + friend class ui::TLSDestructionCheckerForX11; + static bool HasBeenDestroyed(); + + DISALLOW_COPY_AND_ASSIGN(ThreadLocalStorage); +}; + +} // namespace base + +#endif // BASE_THREADING_THREAD_LOCAL_STORAGE_H_ |