security/sandbox/chromium/base/threading/thread_local.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/sandbox/chromium/base/threading/thread_local.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,128 @@
     1.4 +// Copyright (c) 2011 The Chromium Authors. All rights reserved.
     1.5 +// Use of this source code is governed by a BSD-style license that can be
     1.6 +// found in the LICENSE file.
     1.7 +
     1.8 +// WARNING: Thread local storage is a bit tricky to get right.  Please make
     1.9 +// sure that this is really the proper solution for what you're trying to
    1.10 +// achieve.  Don't prematurely optimize, most likely you can just use a Lock.
    1.11 +//
    1.12 +// These classes implement a wrapper around the platform's TLS storage
    1.13 +// mechanism.  On construction, they will allocate a TLS slot, and free the
    1.14 +// TLS slot on destruction.  No memory management (creation or destruction) is
    1.15 +// handled.  This means for uses of ThreadLocalPointer, you must correctly
    1.16 +// manage the memory yourself, these classes will not destroy the pointer for
    1.17 +// you.  There are no at-thread-exit actions taken by these classes.
    1.18 +//
    1.19 +// ThreadLocalPointer<Type> wraps a Type*.  It performs no creation or
    1.20 +// destruction, so memory management must be handled elsewhere.  The first call
    1.21 +// to Get() on a thread will return NULL.  You can update the pointer with a
    1.22 +// call to Set().
    1.23 +//
    1.24 +// ThreadLocalBoolean wraps a bool.  It will default to false if it has never
    1.25 +// been set otherwise with Set().
    1.26 +//
    1.27 +// Thread Safety:  An instance of ThreadLocalStorage is completely thread safe
    1.28 +// once it has been created.  If you want to dynamically create an instance,
    1.29 +// you must of course properly deal with safety and race conditions.  This
    1.30 +// means a function-level static initializer is generally inappropiate.
    1.31 +//
    1.32 +// Example usage:
    1.33 +//   // My class is logically attached to a single thread.  We cache a pointer
    1.34 +//   // on the thread it was created on, so we can implement current().
    1.35 +//   MyClass::MyClass() {
    1.36 +//     DCHECK(Singleton<ThreadLocalPointer<MyClass> >::get()->Get() == NULL);
    1.37 +//     Singleton<ThreadLocalPointer<MyClass> >::get()->Set(this);
    1.38 +//   }
    1.39 +//
    1.40 +//   MyClass::~MyClass() {
    1.41 +//     DCHECK(Singleton<ThreadLocalPointer<MyClass> >::get()->Get() != NULL);
    1.42 +//     Singleton<ThreadLocalPointer<MyClass> >::get()->Set(NULL);
    1.43 +//   }
    1.44 +//
    1.45 +//   // Return the current MyClass associated with the calling thread, can be
    1.46 +//   // NULL if there isn't a MyClass associated.
    1.47 +//   MyClass* MyClass::current() {
    1.48 +//     return Singleton<ThreadLocalPointer<MyClass> >::get()->Get();
    1.49 +//   }
    1.50 +
    1.51 +#ifndef BASE_THREADING_THREAD_LOCAL_H_
    1.52 +#define BASE_THREADING_THREAD_LOCAL_H_
    1.53 +
    1.54 +#include "base/base_export.h"
    1.55 +#include "base/basictypes.h"
    1.56 +
    1.57 +#if defined(OS_POSIX)
    1.58 +#include <pthread.h>
    1.59 +#endif
    1.60 +
    1.61 +namespace base {
    1.62 +
    1.63 +namespace internal {
    1.64 +
    1.65 +// Helper functions that abstract the cross-platform APIs.  Do not use directly.
    1.66 +struct BASE_EXPORT ThreadLocalPlatform {
    1.67 +#if defined(OS_WIN)
    1.68 +  typedef unsigned long SlotType;
    1.69 +#elif defined(OS_POSIX)
    1.70 +  typedef pthread_key_t SlotType;
    1.71 +#endif
    1.72 +
    1.73 +  static void AllocateSlot(SlotType& slot);
    1.74 +  static void FreeSlot(SlotType& slot);
    1.75 +  static void* GetValueFromSlot(SlotType& slot);
    1.76 +  static void SetValueInSlot(SlotType& slot, void* value);
    1.77 +};
    1.78 +
    1.79 +}  // namespace internal
    1.80 +
    1.81 +template <typename Type>
    1.82 +class ThreadLocalPointer {
    1.83 + public:
    1.84 +  ThreadLocalPointer() : slot_() {
    1.85 +    internal::ThreadLocalPlatform::AllocateSlot(slot_);
    1.86 +  }
    1.87 +
    1.88 +  ~ThreadLocalPointer() {
    1.89 +    internal::ThreadLocalPlatform::FreeSlot(slot_);
    1.90 +  }
    1.91 +
    1.92 +  Type* Get() {
    1.93 +    return static_cast<Type*>(
    1.94 +        internal::ThreadLocalPlatform::GetValueFromSlot(slot_));
    1.95 +  }
    1.96 +
    1.97 +  void Set(Type* ptr) {
    1.98 +    internal::ThreadLocalPlatform::SetValueInSlot(
    1.99 +        slot_, const_cast<void*>(static_cast<const void*>(ptr)));
   1.100 +  }
   1.101 +
   1.102 + private:
   1.103 +  typedef internal::ThreadLocalPlatform::SlotType SlotType;
   1.104 +
   1.105 +  SlotType slot_;
   1.106 +
   1.107 +  DISALLOW_COPY_AND_ASSIGN(ThreadLocalPointer<Type>);
   1.108 +};
   1.109 +
   1.110 +class ThreadLocalBoolean {
   1.111 + public:
   1.112 +  ThreadLocalBoolean() { }
   1.113 +  ~ThreadLocalBoolean() { }
   1.114 +
   1.115 +  bool Get() {
   1.116 +    return tlp_.Get() != NULL;
   1.117 +  }
   1.118 +
   1.119 +  void Set(bool val) {
   1.120 +    tlp_.Set(val ? this : NULL);
   1.121 +  }
   1.122 +
   1.123 + private:
   1.124 +  ThreadLocalPointer<void> tlp_;
   1.125 +
   1.126 +  DISALLOW_COPY_AND_ASSIGN(ThreadLocalBoolean);
   1.127 +};
   1.128 +
   1.129 +}  // namespace base
   1.130 +
   1.131 +#endif  // BASE_THREADING_THREAD_LOCAL_H_

mercurial