2023-07-24 18:29:30 +02:00
|
|
|
// Copyright 2023 Joaquin M Lopez Munoz
|
|
|
|
|
// Distributed under the Boost Software License, Version 1.0.
|
|
|
|
|
// https://www.boost.org/LICENSE_1_0.txt
|
|
|
|
|
|
2023-07-25 09:18:53 +02:00
|
|
|
#include <cstdlib>
|
|
|
|
|
|
|
|
|
|
#define BOOST_ENABLE_ASSERT_HANDLER
|
2023-07-24 18:29:30 +02:00
|
|
|
|
|
|
|
|
static bool reentrancy_detected = false;
|
|
|
|
|
|
|
|
|
|
namespace boost {
|
2023-07-25 09:18:53 +02:00
|
|
|
// Caveat lector: a proper handler shouldn't throw as it may be executed
|
2023-07-24 18:29:30 +02:00
|
|
|
// within a noexcept function.
|
|
|
|
|
|
2023-07-25 09:18:53 +02:00
|
|
|
void assertion_failed_msg(
|
|
|
|
|
char const*, char const*, char const*, char const*, long)
|
|
|
|
|
{
|
|
|
|
|
reentrancy_detected = true;
|
|
|
|
|
throw 0;
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-26 12:47:31 +02:00
|
|
|
void assertion_failed(char const*, char const*, char const*, long) // LCOV_EXCL_START
|
2023-07-25 09:18:53 +02:00
|
|
|
{
|
|
|
|
|
std::abort();
|
2023-07-26 12:47:31 +02:00
|
|
|
} // LCOV_EXCL_STOP
|
2023-07-25 09:18:53 +02:00
|
|
|
|
2023-07-24 18:29:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#include <boost/unordered/concurrent_flat_map.hpp>
|
|
|
|
|
#include <boost/core/lightweight_test.hpp>
|
|
|
|
|
|
|
|
|
|
template<typename F>
|
|
|
|
|
void detect_reentrancy(F f)
|
|
|
|
|
{
|
|
|
|
|
reentrancy_detected = false;
|
|
|
|
|
try {
|
|
|
|
|
f();
|
|
|
|
|
}
|
|
|
|
|
catch(int) {}
|
|
|
|
|
BOOST_TEST(reentrancy_detected);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main()
|
|
|
|
|
{
|
|
|
|
|
using map = boost::concurrent_flat_map<int, int>;
|
|
|
|
|
using value_type = typename map::value_type;
|
|
|
|
|
|
|
|
|
|
map m1, m2;
|
|
|
|
|
m1.emplace(0, 0);
|
|
|
|
|
m2.emplace(1, 0);
|
|
|
|
|
|
|
|
|
|
detect_reentrancy([&] {
|
|
|
|
|
m1.visit_all([&](value_type&) { (void)m1.contains(0); });
|
2023-07-26 12:47:31 +02:00
|
|
|
}); // LCOV_EXCL_LINE
|
2023-07-24 18:29:30 +02:00
|
|
|
|
|
|
|
|
detect_reentrancy([&] {
|
|
|
|
|
m1.visit_all([&](value_type&) { m1.rehash(0); });
|
2023-07-26 12:47:31 +02:00
|
|
|
}); // LCOV_EXCL_LINE
|
2023-07-24 18:29:30 +02:00
|
|
|
|
|
|
|
|
detect_reentrancy([&] {
|
|
|
|
|
m1.visit_all([&](value_type&) {
|
|
|
|
|
m2.visit_all([&](value_type&) {
|
|
|
|
|
m1=m2;
|
2023-07-26 12:47:31 +02:00
|
|
|
}); // LCOV_EXCL_START
|
2023-07-24 18:29:30 +02:00
|
|
|
});
|
2023-07-26 12:47:31 +02:00
|
|
|
}); // LCOV_EXCL_STOP
|
2023-07-24 18:29:30 +02:00
|
|
|
|
|
|
|
|
detect_reentrancy([&] {
|
|
|
|
|
m1.visit_all([&](value_type&) {
|
|
|
|
|
m2.visit_all([&](value_type&) {
|
|
|
|
|
m2=m1;
|
2023-07-26 12:47:31 +02:00
|
|
|
}); // LCOV_EXCL_START
|
2023-07-24 18:29:30 +02:00
|
|
|
});
|
2023-07-26 12:47:31 +02:00
|
|
|
}); // LCOV_EXCL_STOP
|
2023-07-24 18:29:30 +02:00
|
|
|
|
|
|
|
|
return boost::report_errors();
|
|
|
|
|
}
|