tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

thread_local.h (2541B)


      1 // Copyright 2011 The Chromium Authors
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // WARNING: Thread local storage is a bit tricky to get right. Please make sure
      6 // that this is really the proper solution for what you're trying to achieve.
      7 // Don't prematurely optimize, most likely you can just use a Lock.
      8 
      9 #ifndef BASE_THREADING_THREAD_LOCAL_H_
     10 #define BASE_THREADING_THREAD_LOCAL_H_
     11 
     12 #include <memory>
     13 
     14 #include "base/dcheck_is_on.h"
     15 #include "base/memory/ptr_util.h"
     16 #include "base/threading/thread_local_internal.h"
     17 #include "base/threading/thread_local_storage.h"
     18 
     19 namespace base {
     20 
     21 // `thread_local` is only allowed for trivially-destructible types (see
     22 // //styleguide/c++/c++.md#thread_local-variables). This class provides
     23 // thread-scoped management of non-trivially-destructible types. Pointers handed
     24 // to it are owned and automatically deleted during their associated thread's
     25 // exit phase (or when replaced if Set() is invoked multiple times on the same
     26 // thread).
     27 //
     28 // The ThreadLocalOwnedPointer instance itself can only be destroyed when no
     29 // threads, other than the one it is destroyed on, have remaining state set in
     30 // it. Typically this means that ThreadLocalOwnedPointer instances are held in
     31 // static storage or at the very least only recycled in the single-threaded
     32 // phase between tests in the same process.
     33 #if DCHECK_IS_ON()
     34 template <typename T>
     35 using ThreadLocalOwnedPointer = internal::CheckedThreadLocalOwnedPointer<T>;
     36 #else   // DCHECK_IS_ON()
     37 template <typename T>
     38 class ThreadLocalOwnedPointer {
     39 public:
     40  ThreadLocalOwnedPointer() = default;
     41 
     42  ThreadLocalOwnedPointer(const ThreadLocalOwnedPointer&) = delete;
     43  ThreadLocalOwnedPointer& operator=(const ThreadLocalOwnedPointer&) = delete;
     44 
     45  ~ThreadLocalOwnedPointer() {
     46    // Assume that this thread is the only one with potential state left. This
     47    // is verified in ~CheckedThreadLocalOwnedPointer().
     48    Set(nullptr);
     49  }
     50 
     51  T* Get() const { return static_cast<T*>(slot_.Get()); }
     52 
     53  // Sets a new value, returns the old.
     54  std::unique_ptr<T> Set(std::unique_ptr<T> ptr) {
     55    auto existing = WrapUnique(Get());
     56    slot_.Set(const_cast<void*>(static_cast<const void*>(ptr.release())));
     57    return existing;
     58  }
     59 
     60  T& operator*() { return *Get(); }
     61 
     62 private:
     63  static void DeleteTlsPtr(void* ptr) { delete static_cast<T*>(ptr); }
     64 
     65  ThreadLocalStorage::Slot slot_{&DeleteTlsPtr};
     66 };
     67 #endif  // DCHECK_IS_ON()
     68 
     69 }  // namespace base
     70 
     71 #endif  // BASE_THREADING_THREAD_LOCAL_H_