Skip to content

Commit 8d16b41

Browse files
committed
several improvements
1 parent dab80b9 commit 8d16b41

File tree

8 files changed

+270
-59
lines changed

8 files changed

+270
-59
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,4 +334,4 @@ jobs:
334334
shell: cmd
335335
run: |
336336
cd ../boost-root
337-
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.platform.toolset}} cxxstd=${{matrix.platform.cxxstd}} address-model=${{matrix.platform.addrmd}} variant=${{matrix.config.variant}}
337+
b2 -j3 --abbreviate-paths libs/%LIBRARY%/test toolset=${{matrix.platform.toolset}} cxxstd=${{matrix.platform.cxxstd}} address-model=${{matrix.platform.addrmd}} link=shared,static exception-handling=on,off variant=${{matrix.config.variant}}

.vscode/tasks.json

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@
133133
"dependsOn": [
134134
"Generate leaf.hpp"
135135
],
136-
"command": "../../b2 test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_single_header,leaf_release_single_header,leaf_debug_embedded,leaf_release_embedded exception-handling=off rtti=off cxxstd=11,14,1z,17 && ../../b2 test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_single_header,leaf_release_single_header exception-handling=on,off cxxstd=11,14,1z,17",
136+
"command": "../../b2 --abbreviate-paths test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_single_header,leaf_release_single_header,leaf_debug_embedded,leaf_release_embedded exception-handling=off rtti=off cxxstd=11,14,1z,17 && ../../b2 --abbreviate-paths test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_single_header,leaf_release_single_header exception-handling=on,off cxxstd=11,14,1z,17",
137137
"problemMatcher": {
138138
"base": "$gcc",
139139
"fileLocation": [
@@ -142,7 +142,7 @@
142142
]
143143
},
144144
"windows": {
145-
"command": "..\\..\\b2 test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_single_header,leaf_release_single_header,leaf_debug_embedded,leaf_release_embedded exception-handling=off rtti=off cxxstd=14,17,latest && ..\\..\\b2 test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_single_header,leaf_release_single_header exception-handling=on,off cxxstd=14,17,latest",
145+
"command": "..\\..\\b2 --abbreviate-paths test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_single_header,leaf_release_single_header,leaf_debug_embedded,leaf_release_embedded exception-handling=off rtti=off cxxstd=14,17,latest && ..\\..\\b2 --abbreviate-paths test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_single_header,leaf_release_single_header exception-handling=on,off cxxstd=14,17,latest",
146146
"problemMatcher": {
147147
"base": "$msCompile",
148148
"fileLocation": [
@@ -159,14 +159,10 @@
159159
},
160160
"label": "Test current editor file",
161161
"type": "shell",
162-
<<<<<<< Updated upstream
163162
"command": "cd ${workspaceRoot}/_bld/debug && ninja && { meson test ${fileBasenameNoExtension} || cat ./meson-logs/testlog.txt; }",,
164163
"windows": {
165164
"command": "cd ${workspaceRoot}/_bld/debug && ninja && (meson test ${fileBasenameNoExtension} || type .\\meson-logs\\testlog.txt)",
166165
},
167-
=======
168-
"command": "cd ${workspaceRoot}/_bld/debug && ninja && {meson test ${fileBasenameNoExtension} || cat ./meson-logs/testlog.txt}",
169-
>>>>>>> Stashed changes
170166
"problemMatcher": {
171167
"base": "$gcc",
172168
"fileLocation": [

include/boost/leaf/config/tls_win32.hpp

Lines changed: 117 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@
1616

1717
#include <atomic>
1818
#include <unordered_map>
19-
#include <typeinfo>
2019
#include <cstdint>
20+
#include <new>
2121
#include <stdexcept>
22-
#include <cstdio>
2322
#include <windows.h>
2423
#ifdef min
2524
# undef min
@@ -41,14 +40,93 @@ class win32_tls_error:
4140
}
4241
};
4342

44-
} }
43+
namespace detail
44+
{
45+
__declspec(noreturn) inline void raise_fail_fast(NTSTATUS status) noexcept
46+
{
47+
EXCEPTION_RECORD rec = {};
48+
rec.ExceptionCode = status;
49+
rec.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
50+
RaiseFailFastException(&rec, nullptr, 0);
51+
__assume(0);
52+
}
4553

46-
////////////////////////////////////////
54+
template <class T, class... Args>
55+
T * heap_new(Args && ... args) noexcept
56+
{
57+
void * mem = HeapAlloc(GetProcessHeap(), 0, sizeof(T));
58+
if (!mem)
59+
{
60+
raise_fail_fast(STATUS_NO_MEMORY);
61+
__assume(0);
62+
}
63+
return new (mem) T(static_cast<Args &&>(args)...);
64+
}
4765

48-
namespace boost { namespace leaf {
66+
template <class T>
67+
void heap_delete(T * p) noexcept
68+
{
69+
if (p)
70+
{
71+
p->~T();
72+
BOOL r = HeapFree(GetProcessHeap(), 0, p);
73+
BOOST_LEAF_ASSERT(r), (void) r;
74+
}
75+
}
76+
77+
template <class T>
78+
class heap_allocator
79+
{
80+
public:
81+
82+
using value_type = T;
83+
84+
heap_allocator() noexcept = default;
85+
86+
template <class U>
87+
heap_allocator(heap_allocator<U> const &) noexcept
88+
{
89+
}
90+
91+
T * allocate(std::size_t n) noexcept
92+
{
93+
if (void * p = HeapAlloc(GetProcessHeap(), 0, n * sizeof(T)))
94+
return static_cast<T *>(p);
95+
raise_fail_fast(STATUS_NO_MEMORY);
96+
__assume(0);
97+
}
98+
99+
void deallocate(T * p, std::size_t) noexcept
100+
{
101+
BOOL r = HeapFree(GetProcessHeap(), 0, p);
102+
BOOST_LEAF_ASSERT(r), (void) r;
103+
}
104+
105+
friend bool operator==(heap_allocator const &, heap_allocator const &) noexcept { return true; }
106+
friend bool operator!=(heap_allocator const &, heap_allocator const &) noexcept { return false; }
107+
};
108+
109+
class critical_section_lock
110+
{
111+
critical_section_lock(critical_section_lock const &) = delete;
112+
critical_section_lock & operator=(critical_section_lock const &) = delete;
113+
114+
CRITICAL_SECTION & cs_;
115+
116+
public:
117+
118+
explicit critical_section_lock(CRITICAL_SECTION & cs) noexcept:
119+
cs_(cs)
120+
{
121+
EnterCriticalSection(&cs_);
122+
}
123+
124+
~critical_section_lock() noexcept
125+
{
126+
LeaveCriticalSection(&cs_);
127+
}
128+
};
49129

50-
namespace detail
51-
{
52130
using atomic_unsigned_int = std::atomic<unsigned int>;
53131

54132
template <int N, int I>
@@ -74,7 +152,7 @@ namespace detail
74152
{
75153
return cpp11_hash_step<N, N - 2>::compute(str, 2166136261u); // str[N-2] is the last character before the \0.
76154
}
77-
}
155+
} // namespace detail
78156

79157
namespace n
80158
{
@@ -94,7 +172,7 @@ namespace detail
94172
}
95173
}
96174

97-
} }
175+
} } // namespace boost::leaf
98176

99177
////////////////////////////////////////
100178

@@ -107,13 +185,6 @@ namespace detail
107185
slot_map(slot_map const &) = delete;
108186
slot_map & operator=(slot_map const &) = delete;
109187

110-
~slot_map() noexcept
111-
{
112-
DeleteCriticalSection(&cs_);
113-
BOOL r = CloseHandle(mapping_);
114-
BOOST_LEAF_ASSERT(r), (void) r;
115-
}
116-
117188
class tls_slot_index
118189
{
119190
tls_slot_index(tls_slot_index const &) = delete;
@@ -156,7 +227,12 @@ namespace detail
156227
HANDLE const mapping_;
157228
tls_slot_index const error_id_slot_;
158229
mutable CRITICAL_SECTION cs_;
159-
std::unordered_map<std::uint32_t, tls_slot_index> map_;
230+
std::unordered_map<
231+
std::uint32_t,
232+
tls_slot_index,
233+
std::hash<std::uint32_t>,
234+
std::equal_to<std::uint32_t>,
235+
heap_allocator<std::pair<std::uint32_t const, tls_slot_index>>> map_;
160236
atomic_unsigned_int error_id_storage_;
161237

162238
public:
@@ -170,6 +246,13 @@ namespace detail
170246
InitializeCriticalSection(&cs_);
171247
}
172248

249+
~slot_map() noexcept
250+
{
251+
DeleteCriticalSection(&cs_);
252+
BOOL r = CloseHandle(mapping_);
253+
BOOST_LEAF_ASSERT(r), (void) r;
254+
}
255+
173256
BOOST_LEAF_ALWAYS_INLINE void add_ref() noexcept
174257
{
175258
BOOST_LEAF_ASSERT(refcount_ >= 1);
@@ -181,23 +264,20 @@ namespace detail
181264
--refcount_;
182265
BOOST_LEAF_ASSERT(refcount_ >= 0);
183266
if (refcount_ == 0)
184-
delete this;
267+
heap_delete(this);
185268
}
186269

187270
DWORD check(std::uint32_t type_hash) const noexcept
188271
{
189-
EnterCriticalSection(&cs_);
272+
critical_section_lock lock(cs_);
190273
auto it = map_.find(type_hash);
191-
DWORD idx = (it != map_.end()) ? it->second.get() : TLS_OUT_OF_INDEXES;
192-
LeaveCriticalSection(&cs_);
193-
return idx;
274+
return (it != map_.end()) ? it->second.get() : TLS_OUT_OF_INDEXES;
194275
}
195276

196277
DWORD get(std::uint32_t type_hash)
197278
{
198-
EnterCriticalSection(&cs_);
279+
critical_section_lock lock(cs_);
199280
DWORD idx = map_[type_hash].get();
200-
LeaveCriticalSection(&cs_);
201281
BOOST_LEAF_ASSERT(idx != TLS_OUT_OF_INDEXES);
202282
return idx;
203283
}
@@ -220,7 +300,6 @@ namespace detail
220300

221301
static constexpr unsigned tls_failure_create_mapping = 0x01;
222302
static constexpr unsigned tls_failure_map_view = 0x02;
223-
static constexpr unsigned tls_failure_slot_map = 0x04;
224303

225304
void * hinstance_;
226305
unsigned tls_failures_;
@@ -240,7 +319,6 @@ namespace detail
240319
BOOST_LEAF_ASSERT(hinstance_);
241320
BOOST_LEAF_ASSERT(!(tls_failures_ & tls_failure_create_mapping));
242321
BOOST_LEAF_ASSERT(!(tls_failures_ & tls_failure_map_view));
243-
BOOST_LEAF_ASSERT(!(tls_failures_ & tls_failure_slot_map));
244322
BOOST_LEAF_ASSERT(sm_);
245323
return *sm_;
246324
}
@@ -250,16 +328,24 @@ namespace detail
250328
if (dwReason == DLL_PROCESS_ATTACH)
251329
{
252330
hinstance_ = hinstDLL;
253-
char name[64];
254-
int num_written = std::snprintf(name, sizeof(name), "Local\\boost_leaf_tls_%lu", GetCurrentProcessId());
255-
BOOST_LEAF_ASSERT(num_written >= 0 && num_written < int(sizeof(name))), (void) num_written;
331+
char name[32] = "Local\\boost_leaf_";
332+
{
333+
constexpr static char const hex[] = "0123456789ABCDEF";
334+
DWORD pid = GetCurrentProcessId();
335+
for (int i = 7; i >= 0; --i)
336+
{
337+
name[17 + i] = hex[pid & 0xf];
338+
pid >>= 4;
339+
}
340+
name[25] = '\0';
341+
}
256342
HANDLE mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, sizeof(slot_map *), name);
343+
DWORD mapping_status = GetLastError();
257344
if (!mapping)
258345
{
259346
tls_failures_ |= tls_failure_create_mapping;
260347
return;
261348
}
262-
DWORD mapping_status = GetLastError();
263349
BOOST_LEAF_ASSERT(mapping_status == ERROR_ALREADY_EXISTS || mapping_status == ERROR_SUCCESS);
264350
bool is_first_module = (mapping_status == ERROR_SUCCESS);
265351
slot_map * * mapped_ptr = static_cast<slot_map * *>(MapViewOfFile(mapping, FILE_MAP_WRITE, 0, 0, sizeof(slot_map *)));
@@ -271,26 +357,7 @@ namespace detail
271357
return;
272358
}
273359
if (is_first_module)
274-
{
275-
#ifndef BOOST_LEAF_NO_EXCEPTIONS
276-
try
277-
{
278-
#endif
279-
sm_ = *mapped_ptr = new slot_map(mapping);
280-
#ifdef BOOST_LEAF_NO_EXCEPTIONS
281-
if (!sm_)
282-
#else
283-
}
284-
catch(...)
285-
#endif
286-
{
287-
tls_failures_ |= tls_failure_slot_map;
288-
EXCEPTION_RECORD rec = {};
289-
rec.ExceptionCode = STATUS_NO_MEMORY;
290-
rec.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
291-
RaiseFailFastException(&rec, nullptr, 0);
292-
}
293-
}
360+
sm_ = *mapped_ptr = heap_new<slot_map>(mapping);
294361
else
295362
{
296363
sm_ = *mapped_ptr;

include/boost/leaf/detail/demangle.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ namespace boost { namespace leaf {
4848
namespace detail
4949
{
5050
// The functions below are C++11 constexpr, but we use BOOST_LEAF_ALWAYS_INLINE to control object file
51-
// section count / template bleat. Evidently this makes a difference on gcc / windows at least.
51+
// section count / template bloat.
5252

5353
template <int S1, int S2, int I, bool = S1 >= S2>
5454
struct cpp11_prefix

include/boost/leaf/error.hpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,18 @@ namespace detail
179179
{
180180
class preloaded_base;
181181

182+
template <class E>
183+
struct capturing_slot_node_allocator;
184+
182185
class dynamic_allocator:
183186
capture_list
184187
{
185188
dynamic_allocator( dynamic_allocator const & ) = delete;
186189
dynamic_allocator & operator=( dynamic_allocator const & ) = delete;
187190

191+
template <class>
192+
friend struct capturing_slot_node_allocator;
193+
188194
preloaded_base * preloaded_list_;
189195

190196
class capturing_node:
@@ -319,7 +325,7 @@ namespace detail
319325
BOOST_LEAF_ASSERT(last_ != nullptr);
320326
BOOST_LEAF_ASSERT(*last_ == nullptr);
321327
BOOST_LEAF_ASSERT(tls::read_ptr<slot<E>>() == nullptr);
322-
capturing_slot_node<E> * csn = new capturing_slot_node<E>(last_);
328+
capturing_slot_node<E> * csn = capturing_slot_node_allocator<E>::new_(last_);
323329
csn->activate();
324330
return csn;
325331
}
@@ -359,6 +365,21 @@ namespace detail
359365
using capture_list::print;
360366
}; // class dynamic_allocator
361367

368+
template <class E>
369+
struct capturing_slot_node_allocator
370+
{
371+
template <class... A>
372+
static dynamic_allocator::capturing_slot_node<E> * new_( A && ... a )
373+
{
374+
return new dynamic_allocator::capturing_slot_node<E>(std::forward<A>(a)...);
375+
}
376+
377+
static void delete_( dynamic_allocator::capturing_slot_node<E> * p ) noexcept
378+
{
379+
delete p;
380+
}
381+
};
382+
362383
template <>
363384
class slot<dynamic_allocator>
364385
{

meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ if option_enable_unit_tests
152152
'on_error_accumulate_nested_new_error_result_test',
153153
'on_error_accumulate_nested_success_exception_test',
154154
'on_error_accumulate_nested_success_result_test',
155+
'on_error_alloc_fail_test',
155156
'on_error_defer_basic_test',
156157
'on_error_defer_nested_error_exception_test',
157158
'on_error_defer_nested_error_result_test',

test/Jamfile.v2

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ run on_error_accumulate_nested_new_error_exception_test.cpp ;
9494
run on_error_accumulate_nested_new_error_result_test.cpp ;
9595
run on_error_accumulate_nested_success_exception_test.cpp ;
9696
run on_error_accumulate_nested_success_result_test.cpp ;
97+
run on_error_alloc_fail_test.cpp ;
9798
run on_error_defer_basic_test.cpp ;
9899
run on_error_defer_nested_error_exception_test.cpp ;
99100
run on_error_defer_nested_error_result_test.cpp ;

0 commit comments

Comments
 (0)