1 // Copyright 2006, Google Inc.
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are met:
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__
30 #include "gears/base/common/common.h"
36 // TODO(mpcomplete): implement these.
37 #if BROWSER_NPAPI && defined(WIN32)
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 //------------------------------------------------------------------------------
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
,
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
);
89 // We keep an entry of this type for each value in the per thread map.
91 Entry() : value_(NULL
), destructor_(NULL
) {}
92 Entry(void *value
, DestructorCallback destructor
) :
93 value_(value
), destructor_(destructor
) {}
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();
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
,
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();
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.
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
);
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();
155 static void FinalizeKey(void *context
);
159 // TODO(mpcomplete): remove.
164 #endif // GEARS_BASE_COMMON_THREAD_LOCALS_H__