Skip to content

Commit feabeca

Browse files
committed
- Refactored TLS implementation, including Win32 support across DLL bondaries
- on_error now allocates dynamic storage (if enabled) before the stack unwind
1 parent 24ad673 commit feabeca

31 files changed

+839
-448
lines changed

include/boost/leaf/common.hpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef BOOST_LEAF_COMMON_HPP_INCLUDED
22
#define BOOST_LEAF_COMMON_HPP_INCLUDED
33

4-
// Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc.
4+
// Copyright 2018-2025 Emil Dotchevski and Reverge Studios, Inc.
55
// Distributed under the Boost Software License, Version 1.0. (See accompanying
66
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
77

@@ -28,26 +28,26 @@
2828

2929
namespace boost { namespace leaf {
3030

31-
struct BOOST_LEAF_SYMBOL_VISIBLE e_api_function { char const * value; };
31+
struct e_api_function { char const * value; };
3232

3333
#if BOOST_LEAF_CFG_STD_STRING
3434

35-
struct BOOST_LEAF_SYMBOL_VISIBLE e_file_name
35+
struct e_file_name
3636
{
3737
std::string value;
3838
};
3939

4040
#else
4141

42-
struct BOOST_LEAF_SYMBOL_VISIBLE e_file_name
42+
struct e_file_name
4343
{
4444
char const * value = "<unavailable>";
4545
BOOST_LEAF_CONSTEXPR explicit e_file_name( char const * ) { }
4646
};
4747

4848
#endif
4949

50-
struct BOOST_LEAF_SYMBOL_VISIBLE e_errno
50+
struct e_errno
5151
{
5252
int value;
5353

@@ -60,9 +60,9 @@ struct BOOST_LEAF_SYMBOL_VISIBLE e_errno
6060
}
6161
};
6262

63-
struct BOOST_LEAF_SYMBOL_VISIBLE e_type_info_name { char const * value; };
63+
struct e_type_info_name { char const * value; };
6464

65-
struct BOOST_LEAF_SYMBOL_VISIBLE e_at_line { int value; };
65+
struct e_at_line { int value; };
6666

6767
namespace windows
6868
{
@@ -104,10 +104,10 @@ namespace windows
104104
}
105105
return os;
106106
}
107-
#endif
107+
#endif // #if BOOST_LEAF_CFG_WIN32
108108
};
109-
}
109+
} // namespace windows
110110

111-
} }
111+
} } // namespace boost::leaf
112112

113-
#endif // BOOST_LEAF_COMMON_HPP_INCLUDED
113+
#endif // #ifndef BOOST_LEAF_COMMON_HPP_INCLUDED

include/boost/leaf/config.hpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef BOOST_LEAF_CONFIG_HPP_INCLUDED
22
#define BOOST_LEAF_CONFIG_HPP_INCLUDED
33

4-
// Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc.
4+
// Copyright 2018-2025 Emil Dotchevski and Reverge Studios, Inc.
55
// Distributed under the Boost Software License, Version 1.0. (See accompanying
66
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
77

@@ -27,7 +27,7 @@
2727
# ifndef BOOST_LEAF_CFG_CAPTURE
2828
# define BOOST_LEAF_CFG_CAPTURE 0
2929
# endif
30-
#endif
30+
#endif // #ifdef BOOST_LEAF_EMBEDDED
3131

3232
////////////////////////////////////////
3333

@@ -162,7 +162,7 @@
162162
# endif
163163
# endif
164164

165-
#endif
165+
#endif // #ifndef BOOST_LEAF_NO_EXCEPTIONS
166166

167167
////////////////////////////////////////
168168

@@ -226,6 +226,8 @@
226226
# define BOOST_LEAF_SYMBOL_VISIBLE
227227
#endif
228228

229+
#include <boost/leaf/config/visibility.hpp>
230+
229231
////////////////////////////////////////
230232

231233
#if defined(__GNUC__) && !(defined(__clang__) || defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) && (__GNUC__ * 100 + __GNUC_MINOR__) < 409
@@ -260,4 +262,4 @@ template <class T>
260262
// Configure TLS access
261263
#include <boost/leaf/config/tls.hpp>
262264

263-
#endif // BOOST_LEAF_CONFIG_HPP_INCLUDED
265+
#endif // #ifndef BOOST_LEAF_CONFIG_HPP_INCLUDED

include/boost/leaf/config/tls.hpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,30 +31,32 @@ namespace tls
3131
// This function may not fail.
3232
unsigned read_current_error_id() noexcept;
3333

34-
// Write p to the TLS for T. The TLS may be allocated dynamically on the
35-
// first call to write_ptr_alloc<T>, but subsequent calls must reuse the
36-
// same TLS.
34+
// Reserve TLS storage for T. The TLS may be allocated dynamically on the
35+
// first call to reserve_ptr<T>, but subsequent calls must reuse the same
36+
// TLS. On platforms where allocation is not needed, this function is
37+
// still defined but does nothing.
3738
//
3839
// This function may throw on allocation failure.
3940
template <class T>
40-
void write_ptr_alloc( T * p );
41+
void reserve_ptr();
4142

42-
// Write p to the TLS previously allocated for T by a successful call to
43-
// write_ptr_alloc<T>.
43+
// Write p to the TLS previously reserved for T by a call to reserve_ptr<T>.
44+
// It is illegal to call write_ptr<T> without a prior successful call to
45+
// reserve_ptr<T>.
4446
//
4547
// This function may not fail.
4648
template <class T>
4749
void write_ptr( T * p ) noexcept;
4850

4951
// Read the T * value previously written in the TLS for T. Returns nullptr
50-
// if TLS for T has not yet been allocated.
52+
// if TLS for T has not yet been reserved.
5153
//
5254
// This function may not fail.
5355
template <class T>
5456
T * read_ptr() noexcept;
55-
}
57+
} // namespace tls
5658

57-
} }
59+
} } // namespace boost::leaf
5860

5961
#if defined(BOOST_LEAF_TLS_FREERTOS)
6062
# include <boost/leaf/config/tls_freertos.hpp>
@@ -85,4 +87,4 @@ namespace tls
8587
# include <boost/leaf/config/tls_cpp11.hpp>
8688
#endif
8789

88-
#endif // BOOST_LEAF_CONFIG_TLS_HPP_INCLUDED
90+
#endif // #ifndef BOOST_LEAF_CONFIG_TLS_HPP_INCLUDED

include/boost/leaf/config/tls_array.hpp

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -100,16 +100,16 @@ namespace detail
100100
BOOST_LEAF_CFG_TLS_INDEX_TYPE tls_index<T>::idx = BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX + 1;
101101

102102
template <class T>
103-
struct BOOST_LEAF_SYMBOL_VISIBLE alloc_tls_index
103+
struct BOOST_LEAF_SYMBOL_VISIBLE reserve_tls_index
104104
{
105105
static BOOST_LEAF_CFG_TLS_INDEX_TYPE const idx;
106106
};
107107

108108
template <class T>
109-
BOOST_LEAF_CFG_TLS_INDEX_TYPE const alloc_tls_index<T>::idx = tls_index<T>::idx = index_counter<>::next<T>();
110-
}
109+
BOOST_LEAF_CFG_TLS_INDEX_TYPE const reserve_tls_index<T>::idx = tls_index<T>::idx = index_counter<>::next<T>();
110+
} // namespace detail
111111

112-
} }
112+
} } // namespace boost::leaf
113113

114114
////////////////////////////////////////
115115

@@ -137,12 +137,9 @@ namespace tls
137137
}
138138

139139
template <class T>
140-
BOOST_LEAF_ALWAYS_INLINE void write_ptr_alloc( T * p )
140+
BOOST_LEAF_ALWAYS_INLINE void reserve_ptr()
141141
{
142-
int tls_idx = detail::alloc_tls_index<T>::idx;
143-
--tls_idx;
144-
write_void_ptr(tls_idx, p);
145-
BOOST_LEAF_ASSERT(read_void_ptr(tls_idx) == p);
142+
(void) detail::reserve_tls_index<T>::idx;
146143
}
147144

148145
template <class T>
@@ -164,8 +161,8 @@ namespace tls
164161
--tls_idx;
165162
return reinterpret_cast<T *>(read_void_ptr(tls_idx));
166163
}
167-
}
164+
} // namespace tls
168165

169-
} }
166+
} } // namespace boost::leaf
170167

171-
#endif // BOOST_LEAF_CONFIG_TLS_ARRAY_HPP_INCLUDED
168+
#endif // #ifndef BOOST_LEAF_CONFIG_TLS_ARRAY_HPP_INCLUDED

include/boost/leaf/config/tls_cpp11.hpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,17 @@ namespace detail
3838
template <class T>
3939
thread_local T * ptr<T>::p;
4040

41-
struct current_error_id_storage
41+
template <class=void>
42+
struct BOOST_LEAF_SYMBOL_VISIBLE current_error_id_storage
4243
{
4344
static thread_local unsigned x;
4445
};
4546

46-
thread_local unsigned current_error_id_storage::x;
47-
}
47+
template <class T>
48+
thread_local unsigned current_error_id_storage<T>::x;
49+
} // namespace detail
4850

49-
} }
51+
} } // namespace boost::leaf
5052

5153
////////////////////////////////////////
5254

@@ -63,18 +65,17 @@ namespace tls
6365

6466
BOOST_LEAF_ALWAYS_INLINE void write_current_error_id( unsigned x ) noexcept
6567
{
66-
detail::current_error_id_storage::x = x;
68+
detail::current_error_id_storage<>::x = x;
6769
}
6870

6971
BOOST_LEAF_ALWAYS_INLINE unsigned read_current_error_id() noexcept
7072
{
71-
return detail::current_error_id_storage::x;
73+
return detail::current_error_id_storage<>::x;
7274
}
7375

7476
template <class T>
75-
BOOST_LEAF_ALWAYS_INLINE void write_ptr_alloc( T * p )
77+
BOOST_LEAF_ALWAYS_INLINE void reserve_ptr()
7678
{
77-
detail::ptr<T>::p = p;
7879
}
7980

8081
template <class T>
@@ -88,8 +89,8 @@ namespace tls
8889
{
8990
return detail::ptr<T>::p;
9091
}
91-
}
92+
} // namespace tls
9293

93-
} }
94+
} } // namespace boost::leaf
9495

95-
#endif // BOOST_LEAF_CONFIG_TLS_CPP11_HPP_INCLUDED
96+
#endif // #ifndef BOOST_LEAF_CONFIG_TLS_CPP11_HPP_INCLUDED

include/boost/leaf/config/tls_globals.hpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ namespace detail
4242

4343
template <class T>
4444
unsigned current_error_id_storage<T>::x = 0;
45-
}
45+
} // namespace detail
4646

47-
} }
47+
} } // namespace boost::leaf
4848

4949
////////////////////////////////////////
5050

@@ -70,9 +70,8 @@ namespace tls
7070
}
7171

7272
template <class T>
73-
BOOST_LEAF_ALWAYS_INLINE void write_ptr_alloc( T * p )
73+
BOOST_LEAF_ALWAYS_INLINE void reserve_ptr()
7474
{
75-
detail::ptr<T>::p = p;
7675
}
7776

7877
template <class T>
@@ -86,8 +85,8 @@ namespace tls
8685
{
8786
return detail::ptr<T>::p;
8887
}
89-
}
88+
} // namespace tls
9089

91-
} }
90+
} } // namespace boost::leaf
9291

93-
#endif // BOOST_LEAF_CONFIG_TLS_GLOBALS_HPP_INCLUDED
92+
#endif // #ifndef BOOST_LEAF_CONFIG_TLS_GLOBALS_HPP_INCLUDED

include/boost/leaf/config/tls_win32.hpp

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ namespace detail
211211
{
212212
return error_id_storage_;
213213
}
214-
};
214+
}; // class slot_map
215215

216216
class module_state
217217
{
@@ -300,14 +300,15 @@ namespace detail
300300
}
301301
else if (dwReason == DLL_PROCESS_DETACH)
302302
{
303+
BOOST_LEAF_ASSERT(sm_ || tls_failures_);
303304
if (sm_)
304305
{
305306
sm_->release();
306307
sm_ = nullptr;
307308
}
308309
}
309310
}
310-
};
311+
}; // class module_state
311312

312313
template<int = 0>
313314
struct module
@@ -334,19 +335,19 @@ namespace detail
334335
#ifdef _MSC_VER
335336
#pragma section(".CRT$XLB", long, read)
336337
#pragma data_seg(push, ".CRT$XLB")
337-
extern "C" PIMAGE_TLS_CALLBACK boost_leaf_tls_callback = tls_callback;
338+
extern "C" __declspec(selectany) PIMAGE_TLS_CALLBACK boost_leaf_tls_callback = tls_callback;
338339
#pragma data_seg(pop)
339340
#ifdef _WIN64
340341
#pragma comment(linker, "/INCLUDE:boost_leaf_tls_callback")
341342
#else
342343
#pragma comment(linker, "/INCLUDE:_boost_leaf_tls_callback")
343344
#endif
344345
#elif defined(__GNUC__)
345-
extern "C" __attribute__((used)) PIMAGE_TLS_CALLBACK boost_leaf_tls_callback __attribute__((section(".CRT$XLB"))) = tls_callback;
346+
extern "C" __attribute__((used, weak)) PIMAGE_TLS_CALLBACK boost_leaf_tls_callback __attribute__((section(".CRT$XLB"))) = tls_callback;
346347
#endif
347-
}
348+
} // namespace detail
348349

349-
} }
350+
} } // namespace boost::leaf
350351

351352
////////////////////////////////////////
352353

@@ -377,14 +378,11 @@ namespace tls
377378
}
378379

379380
template <class T>
380-
BOOST_LEAF_ALWAYS_INLINE void write_ptr_alloc(T * p)
381+
BOOST_LEAF_ALWAYS_INLINE void reserve_ptr()
381382
{
382383
using namespace detail;
383384
thread_local DWORD const cached_slot = module<>::state.sm().get(type_hash<T>());
384-
DWORD slot = cached_slot;
385-
BOOST_LEAF_ASSERT(slot != TLS_OUT_OF_INDEXES);
386-
BOOL r = TlsSetValue(slot, p);
387-
BOOST_LEAF_ASSERT(r), (void) r;
385+
BOOST_LEAF_ASSERT(cached_slot != TLS_OUT_OF_INDEXES), (void) cached_slot;
388386
}
389387

390388
template <class T>
@@ -412,8 +410,8 @@ namespace tls
412410
BOOST_LEAF_ASSERT(GetLastError() == ERROR_SUCCESS);
413411
return static_cast<T *>(value);
414412
}
415-
}
413+
} // namespace tls
416414

417-
} }
415+
} } // namespace boost::leaf
418416

419-
#endif // BOOST_LEAF_CONFIG_TLS_WIN32_HPP_INCLUDED
417+
#endif // #ifndef BOOST_LEAF_CONFIG_TLS_WIN32_HPP_INCLUDED

0 commit comments

Comments
 (0)