Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/thread/src/tss_pe.cpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 5.7 KB
Line 
1// (C) Copyright Aaron W. LaFramboise, Roland Schwarz, Michael Glassford 2004.
2// Use, modification and distribution are subject to the
3// Boost Software License, Version 1.0. (See accompanying file
4// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#include <boost/thread/detail/config.hpp>
7
8#if defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB) && defined(_MSC_VER)
9
10    #include <boost/thread/detail/tss_hooks.hpp>
11
12    #include <stdlib.h>
13
14    #define WIN32_LEAN_AND_MEAN
15    #include <windows.h>
16
17    //Definitions required by implementation
18
19    #if (_MSC_VER < 1300) // 1300 == VC++ 7.0
20        typedef void (__cdecl *_PVFV)(void);
21        #define INIRETSUCCESS
22        #define PVAPI void
23    #else
24        typedef int (__cdecl *_PVFV)(void);
25        #define INIRETSUCCESS 0
26        #define PVAPI int
27    #endif
28
29    typedef void (NTAPI* _TLSCB)(HINSTANCE, DWORD, PVOID);
30
31    //Symbols for connection to the runtime environment
32
33    extern "C"
34    {
35        extern DWORD _tls_used; //the tls directory (located in .rdata segment)
36        extern _TLSCB __xl_a[], __xl_z[];    //tls initializers */
37    }
38
39    namespace
40    {
41        //Forward declarations
42
43        static PVAPI on_tls_prepare(void);
44        static PVAPI on_process_init(void);
45        static PVAPI on_process_term(void);
46        static void NTAPI on_tls_callback(HINSTANCE, DWORD, PVOID);
47
48        //The .CRT$Xxx information is taken from Codeguru:
49        //http://www.codeguru.com/Cpp/misc/misc/threadsprocesses/article.php/c6945__2/
50
51        #if (_MSC_VER >= 1300) // 1300 == VC++ 7.0
52        #   pragma data_seg(push, old_seg)
53        #endif
54            //Callback to run tls glue code first.
55            //I don't think it is necessary to run it
56            //at .CRT$XIB level, since we are only
57            //interested in thread detachement. But
58            //this could be changed easily if required.
59
60            #pragma data_seg(".CRT$XIU")
61            static _PVFV p_tls_prepare = on_tls_prepare;
62            #pragma data_seg()
63
64            //Callback after all global ctors.
65
66            #pragma data_seg(".CRT$XCU")
67            static _PVFV p_process_init = on_process_init;
68            #pragma data_seg()
69
70            //Callback for tls notifications.
71
72            #pragma data_seg(".CRT$XLB")
73            _TLSCB p_thread_callback = on_tls_callback;
74            #pragma data_seg()
75
76            //Callback for termination.
77
78            #pragma data_seg(".CRT$XTU")
79            static _PVFV p_process_term = on_process_term;
80            #pragma data_seg()
81        #if (_MSC_VER >= 1300) // 1300 == VC++ 7.0
82        #   pragma data_seg(pop, old_seg)
83        #endif
84
85        PVAPI on_tls_prepare(void)
86        {
87            //The following line has an important side effect:
88            //if the TLS directory is not already there, it will
89            //be created by the linker. In other words, it forces a tls
90            //directory to be generated by the linker even when static tls
91            //(i.e. __declspec(thread)) is not used.
92            //The volatile should prevent the optimizer
93            //from removing the reference.
94
95            DWORD volatile dw = _tls_used;
96
97            #if (_MSC_VER < 1300) // 1300 == VC++ 7.0
98                _TLSCB* pfbegin = __xl_a;
99                _TLSCB* pfend = __xl_z;
100                _TLSCB* pfdst = pfbegin;
101                //pfdst = (_TLSCB*)_tls_used.AddressOfCallBacks;
102
103                //The following loop will merge the address pointers
104                //into a contiguous area, since the tlssup code seems
105                //to require this (at least on MSVC 6)
106
107                while (pfbegin < pfend)
108                {
109                    if (*pfbegin != 0)
110                    {
111                        *pfdst = *pfbegin;
112                        ++pfdst;
113                    }
114                    ++pfbegin;
115                }
116
117                *pfdst = 0;
118            #endif
119
120            return INIRETSUCCESS;
121        }
122
123        PVAPI on_process_init(void)
124        {
125            //Schedule on_thread_exit() to be called for the main
126            //thread before destructors of global objects have been
127            //called.
128
129            //It will not be run when 'quick' exiting the
130            //library; however, this is the standard behaviour
131            //for destructors of global objects, so that
132            //shouldn't be a problem.
133
134            atexit(on_thread_exit);
135
136            //Call Boost process entry callback here
137
138            on_process_enter();
139
140            return INIRETSUCCESS;
141        }
142
143        PVAPI on_process_term(void)
144        {
145            on_process_exit();
146            return INIRETSUCCESS;
147        }
148
149        void NTAPI on_tls_callback(HINSTANCE h, DWORD dwReason, PVOID pv)
150        {
151            switch (dwReason)
152            {
153                case DLL_THREAD_DETACH:
154                {
155                    on_thread_exit();
156                    break;
157                }
158            }
159        }
160    } //namespace
161
162    extern "C" void tss_cleanup_implemented(void)
163    {
164        /*
165        This function's sole purpose is to cause a link error in cases where
166        automatic tss cleanup is not implemented by Boost.Threads as a
167        reminder that user code is responsible for calling the necessary
168        functions at the appropriate times (and for implementing an a
169        tss_cleanup_implemented() function to eliminate the linker's
170        missing symbol error).
171
172        If Boost.Threads later implements automatic tss cleanup in cases
173        where it currently doesn't (which is the plan), the duplicate
174        symbol error will warn the user that their custom solution is no
175        longer needed and can be removed.
176        */
177    }
178
179#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB)
Note: See TracBrowser for help on using the repository browser.