]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/thread/src/win32/tss_pe.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / thread / src / win32 / tss_pe.cpp
CommitLineData
7c673cae
FG
1// $Id$
2// (C) Copyright Aaron W. LaFramboise, Roland Schwarz, Michael Glassford 2004.
3// (C) Copyright 2007 Roland Schwarz
4// (C) Copyright 2007 Anthony Williams
5// (C) Copyright 2007 David Deakins
6// Use, modification and distribution are subject to the
7// Boost Software License, Version 1.0. (See accompanying file
8// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
10#include <boost/detail/winapi/config.hpp>
11#include <boost/thread/detail/config.hpp>
12
b32b8144 13#if defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB)
7c673cae
FG
14
15#if (defined(__MINGW32__) && !defined(_WIN64)) || defined(__MINGW64__) || (__MINGW64_VERSION_MAJOR)
16
17#include <boost/thread/detail/tss_hooks.hpp>
18
19#include <windows.h>
20
21#include <cstdlib>
22
23namespace boost
24{
25 void tss_cleanup_implemented() {}
26}
27
28namespace {
29 void NTAPI on_tls_callback(void* , DWORD dwReason, PVOID )
30 {
31 switch (dwReason)
32 {
33 case DLL_THREAD_DETACH:
34 {
35 boost::on_thread_exit();
36 break;
37 }
38 }
39 }
40}
41
b32b8144 42#if defined(__MINGW64__) || (__MINGW64_VERSION_MAJOR) || (__MINGW32__) || (__MINGW32_MAJOR_VERSION >3) || \
7c673cae
FG
43 ((__MINGW32_MAJOR_VERSION==3) && (__MINGW32_MINOR_VERSION>=18))
44extern "C"
45{
46 PIMAGE_TLS_CALLBACK __crt_xl_tls_callback__ __attribute__ ((section(".CRT$XLB"))) = on_tls_callback;
47}
48#else
49extern "C" {
50
51 void (* after_ctors )() __attribute__((section(".ctors"))) = boost::on_process_enter;
52 void (* before_dtors)() __attribute__((section(".dtors"))) = boost::on_thread_exit;
53 void (* after_dtors )() __attribute__((section(".dtors.zzz"))) = boost::on_process_exit;
54
55 ULONG __tls_index__ = 0;
56 char __tls_end__ __attribute__((section(".tls$zzz"))) = 0;
57 char __tls_start__ __attribute__((section(".tls"))) = 0;
58
59
60 PIMAGE_TLS_CALLBACK __crt_xl_start__ __attribute__ ((section(".CRT$XLA"))) = 0;
61 PIMAGE_TLS_CALLBACK __crt_xl_end__ __attribute__ ((section(".CRT$XLZ"))) = 0;
62}
63extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata$T"))) =
64{
65 (DWORD) &__tls_start__,
66 (DWORD) &__tls_end__,
67 (DWORD) &__tls_index__,
68 (DWORD) (&__crt_xl_start__+1),
69 (DWORD) 0,
70 (DWORD) 0
71};
72#endif
73
74
75#elif defined(_MSC_VER) && !defined(UNDER_CE)
76
77 #include <boost/thread/detail/tss_hooks.hpp>
78
79 #include <stdlib.h>
80
81 #include <windows.h>
82
83
84// _pRawDllMainOrig can be defined by including boost/thread/win32/mfc_thread_init.hpp
85// into your dll; it ensures that MFC-Dll-initialization will be done properly
86// The following code is adapted from the MFC-Dll-init code
87/*
88 * _pRawDllMainOrig MUST be an extern const variable, which will be aliased to
89 * _pDefaultRawDllMainOrig if no real user definition is present, thanks to the
90 * alternatename directive.
91 */
92
93// work at least with _MSC_VER 1500 (MSVC++ 9.0, VS 2008)
94#if (_MSC_VER >= 1500)
95
96extern "C" {
b32b8144
FG
97extern BOOL (WINAPI * const _pRawDllMainOrig)(HINSTANCE, DWORD, LPVOID);
98extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HINSTANCE, DWORD, LPVOID) = NULL;
7c673cae
FG
99#if defined (_M_IX86)
100#pragma comment(linker, "/alternatename:__pRawDllMainOrig=__pDefaultRawDllMainOrig")
101#elif defined (_M_X64) || defined (_M_ARM)
102#pragma comment(linker, "/alternatename:_pRawDllMainOrig=_pDefaultRawDllMainOrig")
103#else /* defined (_M_X64) || defined (_M_ARM) */
104#error Unsupported platform
105#endif /* defined (_M_X64) || defined (_M_ARM) */
106}
107
108#endif
109
110
111
112
113 //Definitions required by implementation
b32b8144
FG
114 #if (_MSC_VER < 1300) || ((_MSC_VER > 1900) && (_MSC_VER < 1910)) // 1300 == VC++ 7.0, 1900 == VC++ 14.0, 1910 == VC++ 2017
115 typedef void ( __cdecl *_PVFV_ )();
116 typedef void ( __cdecl *_PIFV_ )();
117 #define INIRETSUCCESS_V
118 #define INIRETSUCCESS_I
119 #define PVAPI_V void __cdecl
120 #define PVAPI_I void __cdecl
121 #elif (_MSC_VER >= 1910)
122 typedef void ( __cdecl *_PVFV_ )();
123 typedef int ( __cdecl *_PIFV_ )();
124 #define INIRETSUCCESS_V
125 #define INIRETSUCCESS_I 0
126 #define PVAPI_V void __cdecl
127 #define PVAPI_I int __cdecl
7c673cae 128 #else
b32b8144
FG
129 typedef int ( __cdecl *_PVFV_ )();
130 typedef int ( __cdecl *_PIFV_ )();
131 #define INIRETSUCCESS_V 0
132 #define INIRETSUCCESS_I 0
133 #define PVAPI_V int __cdecl
134 #define PVAPI_I int __cdecl
7c673cae
FG
135 #endif
136
137 typedef void (NTAPI* _TLSCB)(HINSTANCE, DWORD, PVOID);
138
139 //Symbols for connection to the runtime environment
140
141 extern "C"
142 {
143 extern DWORD _tls_used; //the tls directory (located in .rdata segment)
144 extern _TLSCB __xl_a[], __xl_z[]; //tls initializers */
145 }
146
147 namespace
148 {
149 //Forward declarations
150
b32b8144
FG
151 static PVAPI_I on_tls_prepare();
152 static PVAPI_V on_process_init();
153 static PVAPI_V on_process_term();
7c673cae
FG
154 static void NTAPI on_tls_callback(HINSTANCE, DWORD, PVOID);
155
156 //The .CRT$Xxx information is taken from Codeguru:
157 //http://www.codeguru.com/Cpp/misc/misc/threadsprocesses/article.php/c6945__2/
158
159#if (_MSC_VER >= 1400)
160#pragma section(".CRT$XIU",long,read)
161#pragma section(".CRT$XCU",long,read)
162#pragma section(".CRT$XTU",long,read)
163#pragma section(".CRT$XLC",long,read)
164 __declspec(allocate(".CRT$XLC")) _TLSCB __xl_ca=on_tls_callback;
b32b8144
FG
165 __declspec(allocate(".CRT$XIU"))_PIFV_ p_tls_prepare = on_tls_prepare;
166 __declspec(allocate(".CRT$XCU"))_PVFV_ p_process_init = on_process_init;
167 __declspec(allocate(".CRT$XTU"))_PVFV_ p_process_term = on_process_term;
7c673cae
FG
168#else
169 #if (_MSC_VER >= 1300) // 1300 == VC++ 7.0
170 # pragma data_seg(push, old_seg)
171 #endif
172 //Callback to run tls glue code first.
173 //I don't think it is necessary to run it
174 //at .CRT$XIB level, since we are only
175 //interested in thread detachement. But
176 //this could be changed easily if required.
177
178 #pragma data_seg(".CRT$XIU")
b32b8144 179 static _PIFV_ p_tls_prepare = on_tls_prepare;
7c673cae
FG
180 #pragma data_seg()
181
182 //Callback after all global ctors.
183
184 #pragma data_seg(".CRT$XCU")
b32b8144 185 static _PVFV_ p_process_init = on_process_init;
7c673cae
FG
186 #pragma data_seg()
187
188 //Callback for tls notifications.
189
190 #pragma data_seg(".CRT$XLB")
191 _TLSCB p_thread_callback = on_tls_callback;
192 #pragma data_seg()
193 //Callback for termination.
194
195 #pragma data_seg(".CRT$XTU")
b32b8144 196 static _PVFV_ p_process_term = on_process_term;
7c673cae
FG
197 #pragma data_seg()
198 #if (_MSC_VER >= 1300) // 1300 == VC++ 7.0
199 # pragma data_seg(pop, old_seg)
200 #endif
201#endif
202
203#ifdef BOOST_MSVC
204#pragma warning(push)
205#pragma warning(disable:4189)
206#endif
207
b32b8144 208 PVAPI_I on_tls_prepare()
7c673cae
FG
209 {
210 //The following line has an important side effect:
211 //if the TLS directory is not already there, it will
212 //be created by the linker. In other words, it forces a tls
213 //directory to be generated by the linker even when static tls
214 //(i.e. __declspec(thread)) is not used.
215 //The volatile should prevent the optimizer
216 //from removing the reference.
217
218 DWORD volatile dw = _tls_used;
219
220 #if (_MSC_VER < 1300) // 1300 == VC++ 7.0
221 _TLSCB* pfbegin = __xl_a;
222 _TLSCB* pfend = __xl_z;
223 _TLSCB* pfdst = pfbegin;
224 //pfdst = (_TLSCB*)_tls_used.AddressOfCallBacks;
225
226 //The following loop will merge the address pointers
227 //into a contiguous area, since the tlssup code seems
228 //to require this (at least on MSVC 6)
229
230 while (pfbegin < pfend)
231 {
232 if (*pfbegin != 0)
233 {
234 *pfdst = *pfbegin;
235 ++pfdst;
236 }
237 ++pfbegin;
238 }
239
240 *pfdst = 0;
241 #endif
242
b32b8144 243 return INIRETSUCCESS_I;
7c673cae
FG
244 }
245#ifdef BOOST_MSVC
246#pragma warning(pop)
247#endif
248
b32b8144 249 PVAPI_V on_process_init()
7c673cae
FG
250 {
251 //Schedule on_thread_exit() to be called for the main
252 //thread before destructors of global objects have been
253 //called.
254
255 //It will not be run when 'quick' exiting the
256 //library; however, this is the standard behaviour
257 //for destructors of global objects, so that
258 //shouldn't be a problem.
259
260 atexit(boost::on_thread_exit);
261
262 //Call Boost process entry callback here
263
264 boost::on_process_enter();
265
b32b8144 266 return INIRETSUCCESS_V;
7c673cae
FG
267 }
268
b32b8144 269 PVAPI_V on_process_term()
7c673cae
FG
270 {
271 boost::on_process_exit();
b32b8144 272 return INIRETSUCCESS_V;
7c673cae
FG
273 }
274
275 void NTAPI on_tls_callback(HINSTANCE /*h*/, DWORD dwReason, PVOID /*pv*/)
276 {
277 switch (dwReason)
278 {
279 case DLL_THREAD_DETACH:
280 boost::on_thread_exit();
281 break;
282 }
283 }
284
285#if (_MSC_VER >= 1500)
b32b8144 286 BOOL WINAPI dll_callback(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
7c673cae 287#else
b32b8144 288 BOOL WINAPI dll_callback(HINSTANCE, DWORD dwReason, LPVOID)
7c673cae
FG
289#endif
290 {
291 switch (dwReason)
292 {
293 case DLL_THREAD_DETACH:
294 boost::on_thread_exit();
295 break;
296 case DLL_PROCESS_DETACH:
297 boost::on_process_exit();
298 break;
299 }
300
301#if (_MSC_VER >= 1500)
302 if( _pRawDllMainOrig )
303 {
304 return _pRawDllMainOrig(hInstance, dwReason, lpReserved);
305 }
306#endif
307 return true;
308 }
309 } //namespace
310
311extern "C"
312{
b32b8144 313 extern BOOL (WINAPI * const _pRawDllMain)(HINSTANCE, DWORD, LPVOID)=&dll_callback;
7c673cae
FG
314}
315namespace boost
316{
317 void tss_cleanup_implemented()
318 {
319 /*
320 This function's sole purpose is to cause a link error in cases where
321 automatic tss cleanup is not implemented by Boost.Threads as a
322 reminder that user code is responsible for calling the necessary
323 functions at the appropriate times (and for implementing an a
324 tss_cleanup_implemented() function to eliminate the linker's
325 missing symbol error).
326
327 If Boost.Threads later implements automatic tss cleanup in cases
328 where it currently doesn't (which is the plan), the duplicate
329 symbol error will warn the user that their custom solution is no
330 longer needed and can be removed.
331 */
332 }
333}
334
335#endif //defined(_MSC_VER) && !defined(UNDER_CE)
336
337#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB)