Home | History | Annotate | Download | only in threading
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef BASE_THREADING_THREAD_LOCAL_STORAGE_H_
      6 #define BASE_THREADING_THREAD_LOCAL_STORAGE_H_
      7 #pragma once
      8 
      9 #include "base/base_api.h"
     10 #include "base/basictypes.h"
     11 
     12 #if defined(OS_POSIX)
     13 #include <pthread.h>
     14 #endif
     15 
     16 namespace base {
     17 
     18 // Wrapper for thread local storage.  This class doesn't do much except provide
     19 // an API for portability.
     20 class BASE_API ThreadLocalStorage {
     21  public:
     22 
     23   // Prototype for the TLS destructor function, which can be optionally used to
     24   // cleanup thread local storage on thread exit.  'value' is the data that is
     25   // stored in thread local storage.
     26   typedef void (*TLSDestructorFunc)(void* value);
     27 
     28   // A key representing one value stored in TLS.
     29   class BASE_API Slot {
     30    public:
     31     explicit Slot(TLSDestructorFunc destructor = NULL);
     32 
     33     // This constructor should be used for statics.
     34     // It returns an uninitialized Slot.
     35     explicit Slot(base::LinkerInitialized x) {}
     36 
     37     // Set up the TLS slot.  Called by the constructor.
     38     // 'destructor' is a pointer to a function to perform per-thread cleanup of
     39     // this object.  If set to NULL, no cleanup is done for this TLS slot.
     40     // Returns false on error.
     41     bool Initialize(TLSDestructorFunc destructor);
     42 
     43     // Free a previously allocated TLS 'slot'.
     44     // If a destructor was set for this slot, removes
     45     // the destructor so that remaining threads exiting
     46     // will not free data.
     47     void Free();
     48 
     49     // Get the thread-local value stored in slot 'slot'.
     50     // Values are guaranteed to initially be zero.
     51     void* Get() const;
     52 
     53     // Set the thread-local value stored in slot 'slot' to
     54     // value 'value'.
     55     void Set(void* value);
     56 
     57     bool initialized() const { return initialized_; }
     58 
     59    private:
     60     // The internals of this struct should be considered private.
     61     bool initialized_;
     62 #if defined(OS_WIN)
     63     int slot_;
     64 #elif defined(OS_POSIX)
     65     pthread_key_t key_;
     66 #endif
     67 
     68     DISALLOW_COPY_AND_ASSIGN(Slot);
     69   };
     70 
     71 #if defined(OS_WIN)
     72   // Function called when on thread exit to call TLS
     73   // destructor functions.  This function is used internally.
     74   static void ThreadExit();
     75 
     76  private:
     77   // Function to lazily initialize our thread local storage.
     78   static void **Initialize();
     79 
     80  private:
     81   // The maximum number of 'slots' in our thread local storage stack.
     82   // For now, this is fixed.  We could either increase statically, or
     83   // we could make it dynamic in the future.
     84   static const int kThreadLocalStorageSize = 64;
     85 
     86   static long tls_key_;
     87   static long tls_max_;
     88   static TLSDestructorFunc tls_destructors_[kThreadLocalStorageSize];
     89 #endif  // OS_WIN
     90 
     91   DISALLOW_COPY_AND_ASSIGN(ThreadLocalStorage);
     92 };
     93 
     94 }  // namespace base
     95 
     96 #endif  // BASE_THREADING_THREAD_LOCAL_STORAGE_H_
     97