TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / external / android-emugl / shared / emugl / common / thread_store.h
1 // Copyright (C) 2014 The Android Open Source Project
2 //
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
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
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.
14
15 #ifndef EMUGL_COMMON_THREAD_STORE_H
16 #define EMUGL_COMMON_THREAD_STORE_H
17
18 #ifdef _WIN32
19 #  define WIN32_LEAN_AND_MEAN 1
20 #  include <windows.h>
21 #else
22 #  include <pthread.h>
23 #endif
24
25 namespace emugl {
26
27 // A class to model storage of thread-specific values, that can be
28 // destroyed on thread exit.
29 //
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.
34 //
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.
38 //
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.
44 //
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
49 // program exit.
50 //
51 // [1] http://stackoverflow.com/questions/14538159/about-tls-callback-in-windows
52
53 class ThreadStore {
54 public:
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);
58
59     // Initialize instance so that is hold keys that must be destroyed
60     // on thread exit by calling |destroy|.
61     explicit ThreadStore(Destructor* destroy);
62
63     // NOTE: Destructor don't free the thread-local values, but are required
64     // to avoid crashes (see note above).
65     ~ThreadStore();
66
67     // Retrieve current thread-specific value from store.
68 #ifdef _WIN32
69     void* get() const;
70 #else
71     inline void* get() const {
72         return pthread_getspecific(mKey);
73     }
74 #endif
75
76     // Set the new thread-specific value.
77 #ifdef _WIN32
78     void set(void* value);
79 #else
80     inline void set(void* value) {
81         pthread_setspecific(mKey, value);
82     }
83 #endif
84
85 #ifdef _WIN32
86     // Each thread should call this function on exit to ensure that
87     // all corresponding TLS values are properly freed.
88     static void OnThreadExit();
89 #else
90     // Nothing to do on Posix.
91     static inline void OnThreadExit() {}
92 #endif
93
94 private:
95     // Ensure you can't create an empty ThreadStore instance, or simply
96     // copy it in any way.
97     ThreadStore();
98     ThreadStore(const ThreadStore&);
99     ThreadStore& operator=(const ThreadStore&);
100
101 #ifdef _WIN32
102     int mKey;
103 #else
104     pthread_key_t mKey;
105 #endif
106 };
107
108 }  // namespace emugl
109
110 #endif  // EMUGL_COMMON_THREAD_STORE_H