1 // Copyright (C) 2014 The Android Open Source Project
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 #ifndef EMUGL_COMMON_THREAD_STORE_H
16 #define EMUGL_COMMON_THREAD_STORE_H
19 # define WIN32_LEAN_AND_MEAN 1
27 // A class to model storage of thread-specific values, that can be
28 // destroyed on thread exit.
30 // Note that on Windows, a thread must call OnThreadExit() explicitly
31 // here to ensure that the values are probably discarded. This is an
32 // unfortunate requirement of the Win32 API, which doesn't support
33 // destructors at all.
35 // There are various hacks on the web to try to achieve this automatically
36 // (e.g. [1]) but they rely on using the Microsoft build tools,
37 // which doesn't work for us.
39 // Note another important issue with ThreadStore instances: if you create
40 // one instance in a shared library, you need to make sure that it is
41 // always destroyed before the library is unloaded. Otherwise, future
42 // thread exit will likely crash, due to calling a destructor function
43 // that is no longer in the process' address space.
45 // Finally, destroying an instance does _not_ free the corresponding values,
46 // because doing so properly requires coordinating all participating threads,
47 // which is impossible to achieve in the most general case. Thus, consider
48 // that thread-local values are always leaked on library unload, or on
51 // [1] http://stackoverflow.com/questions/14538159/about-tls-callback-in-windows
55 // Type of a function used to destroy a thread-specific value that
56 // was previously assigned by calling set().
57 typedef void (Destructor)(void* value);
59 // Initialize instance so that is hold keys that must be destroyed
60 // on thread exit by calling |destroy|.
61 explicit ThreadStore(Destructor* destroy);
63 // NOTE: Destructor don't free the thread-local values, but are required
64 // to avoid crashes (see note above).
67 // Retrieve current thread-specific value from store.
71 inline void* get() const {
72 return pthread_getspecific(mKey);
76 // Set the new thread-specific value.
78 void set(void* value);
80 inline void set(void* value) {
81 pthread_setspecific(mKey, value);
86 // Each thread should call this function on exit to ensure that
87 // all corresponding TLS values are properly freed.
88 static void OnThreadExit();
90 // Nothing to do on Posix.
91 static inline void OnThreadExit() {}
95 // Ensure you can't create an empty ThreadStore instance, or simply
96 // copy it in any way.
98 ThreadStore(const ThreadStore&);
99 ThreadStore& operator=(const ThreadStore&);
110 #endif // EMUGL_COMMON_THREAD_STORE_H