[Author: andreip]
[google-gears.git] / gears / base / common / thread_locals.h
blobd5a1c704765001ecd2508655aa83c4a063bc4b2e
1 // Copyright 2006, Google Inc.
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are met:
5 //
6 // 1. Redistributions of source code must retain the above copyright notice,
7 // this list of conditions and the following disclaimer.
8 // 2. Redistributions in binary form must reproduce the above copyright notice,
9 // this list of conditions and the following disclaimer in the documentation
10 // and/or other materials provided with the distribution.
11 // 3. Neither the name of Google Inc. nor the names of its contributors may be
12 // used to endorse or promote products derived from this software without
13 // specific prior written permission.
15 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
18 // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #ifndef GEARS_BASE_COMMON_THREAD_LOCALS_H__
27 #define GEARS_BASE_COMMON_THREAD_LOCALS_H__
29 #include <map>
30 #include "gears/base/common/common.h"
32 #if BROWSER_SAFARI
33 #include <pthread.h>
34 #endif
36 // TODO(mpcomplete): implement these.
37 #if BROWSER_NPAPI && defined(WIN32)
38 #define BROWSER_IE 1
39 #endif
41 //------------------------------------------------------------------------------
42 // Provides for per thread-local storage in a win32 DLL. This classes allocates
43 // a single TLS index from the OS, and keeps multiple entries in a map
44 // stored in that per-thread slot.
46 // Users of this class should follow the convention module:name to avoid
47 // conflicts in keys. For example, "base:permissions".
48 //------------------------------------------------------------------------------
49 class ThreadLocals {
50 public:
52 // Destructor callback used to destroy a value when a thread terminates.
53 typedef void (*DestructorCallback)(void*);
55 // Returns the thread-local value for the given key. If no value
56 // has been stored with this key, returns NULL.
57 // @key, the key of the value to retrieve
58 static void *GetValue(const std::string &key);
60 // Returns whether or not a thread-local value exists for the given key.
61 // @key, the key of the value to test
62 static bool HasValue(const std::string &key);
64 // Sets the thead local value and its destructor for the given key. When the
65 // thread terminates, the destructor (if non-null) will be called. If a value
66 // for the key already exists, the old value is destroyed and its entry is
67 // replaced with the new value.
68 // @key, the key of the value to set
69 // @value, the value to store for the current thread
70 // @destructor, optional destructor callback that will be invoked
71 // when the value is cleared (by DestroyValue) or when
72 // the thread dies, can be null. Note that the thread
73 // the destructor is called in may differ across
74 // platforms. For DestroyValue, it should always be
75 // the same thread SetValue was called from. On thread
76 // death under Windows, the destructor is called in the
77 // same thread SetValue() was called from. On thread
78 // death under Firefox on Linux and MacOS X, the
79 // destructor is called in the joining thread.
80 static void SetValue(const std::string &key,
81 void *value,
82 DestructorCallback destructor);
84 // Destroys the thread-local value for the given key and clears its entry.
85 // @key, the key of value to destroy
86 static void DestroyValue(const std::string &key);
88 private:
89 // We keep an entry of this type for each value in the per thread map.
90 struct Entry {
91 Entry() : value_(NULL), destructor_(NULL) {}
92 Entry(void *value, DestructorCallback destructor) :
93 value_(value), destructor_(destructor) {}
94 void *value_;
95 DestructorCallback destructor_;
97 typedef std::map< std::string, Entry > Map;
99 // Returns the map associated with the currently executing thread, optionally
100 // creating the map if one does not already exist.
101 static Map *GetMap(bool createIfNeeded);
103 static void DestroyMap(Map* map);
104 static void SetTlsMap(Map* map);
105 static Map* GetTlsMap();
107 #if BROWSER_IE
108 // We use one thread-local storage slot from the OS and keeps a map
109 // in that slot. This is the index of that slot as returned by TlsAlloc.
110 static DWORD tls_index_;
112 // Some private methods of this class need to be called by the containing DLL.
113 // We declare the function that calls these methods a friend.
114 // @see base/ie/module.cc
115 friend inline BOOL MyDllMain(HANDLE instance,
116 DWORD reason,
117 LPVOID reserved);
119 // Should be called when the DLL is loading. If FALSE is returned, the DLL
120 // should fail to load.
121 static BOOL HandleProcessAttached();
123 // Should be called when the DLL is unloading or the process is existing.
124 static void HandleProcessDetached();
126 // Should be called when a thread is terminating.
127 static void HandleThreadDetached();
128 #elif BROWSER_FF
129 // We use one thread-local storage slot from the OS and keeps a map
130 // in that slot. This is the index of that slot as returned by TlsAlloc.
131 static PRUintn tls_index_;
133 // Some private methods of this class need to be called by the containing DLL.
134 // We declare the function that calls these methods a friend.
135 // @see module.cc
136 friend nsresult PR_CALLBACK ScourModuleConstructor(class nsIModule* self);
138 // Should be called when the DLL is loading. If an error is returned the DLL
139 // should fail to load.
140 static nsresult HandleModuleConstructed();
142 // Called by NSPR when the value in our TLS slot is destructed.
143 static void PR_CALLBACK TlsDestructor(void *priv);
144 #elif BROWSER_SAFARI
145 // The pthread key to use to save the map
146 static pthread_key_t tls_index_;
148 // Ensure that the map key is initialized only once
149 static pthread_once_t tls_index_init_;
151 // Initialize the key
152 static void InitializeKey();
154 // Finalize the key
155 static void FinalizeKey(void *context);
156 #endif
159 // TODO(mpcomplete): remove.
160 #if BROWSER_NPAPI
161 #undef BROWSER_IE
162 #endif
164 #endif // GEARS_BASE_COMMON_THREAD_LOCALS_H__