Files
unordered/test/cfoa/reentrancy_check_test.cpp

120 lines
2.9 KiB
C++
Raw Normal View History

// Copyright 2023-2024 Joaquin M Lopez Munoz
2023-07-24 18:29:30 +02:00
// 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-09-10 18:35:51 +02:00
void assertion_failed_msg(
char const*, char const*, char const*, char const*, long)
{
reentrancy_detected = true;
throw 0;
}
2023-07-25 09:18:53 +02:00
2023-09-10 18:35:51 +02:00
// LCOV_EXCL_START
void assertion_failed(char const*, char const*, char const*, long)
{
std::abort();
}
// LCOV_EXCL_STOP
2023-07-25 09:18:53 +02:00
2023-09-10 18:35:51 +02:00
} // namespace boost
#include "helpers.hpp"
2023-07-24 18:29:30 +02:00
#include <boost/unordered/concurrent_flat_map.hpp>
2023-09-10 18:35:51 +02:00
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
2023-07-24 18:29:30 +02:00
#include <boost/core/lightweight_test.hpp>
2023-09-10 18:35:51 +02:00
using test::default_generator;
using map_type = boost::unordered::concurrent_flat_map<raii, raii>;
using node_map_type = boost::unordered::concurrent_node_map<raii, raii>;
2023-09-10 18:35:51 +02:00
using set_type = boost::unordered::concurrent_flat_set<raii>;
using node_set_type = boost::unordered::concurrent_node_set<raii>;
2023-09-10 18:35:51 +02:00
map_type* test_map;
map_type* test_node_map;
2023-09-10 18:35:51 +02:00
set_type* test_set;
node_set_type* test_node_set;
2023-09-10 18:35:51 +02:00
2023-07-24 18:29:30 +02:00
template<typename F>
void detect_reentrancy(F f)
{
reentrancy_detected = false;
try {
f();
}
catch(int) {}
BOOST_TEST(reentrancy_detected);
}
2023-09-10 18:35:51 +02:00
namespace {
template <class X, class GF>
void reentrancy_tests(X*, GF gen_factory, test::random_generator rg)
{
using key_type = typename X::key_type;
// concurrent_flat_set visit is always const access
using arg_type = typename std::conditional<
std::is_same<typename X::key_type, typename X::value_type>::value,
typename X::value_type const,
typename X::value_type
>::type;
auto gen = gen_factory.template get<X>();
auto values = make_random_values(1024 * 16, [&] { return gen(rg); });
X x1, x2;
x1.insert(values.begin(), values.end());
x2.insert(values.begin(), values.end());
detect_reentrancy([&] {
x1.visit_all([&](arg_type&) { (void)x1.contains(key_type()); });
}); // LCOV_EXCL_LINE
detect_reentrancy([&] {
x1.visit_all([&](arg_type&) { x1.rehash(0); });
}); // LCOV_EXCL_LINE
detect_reentrancy([&] {
x1.visit_all([&](arg_type&) {
x2.visit_all([&](arg_type&) {
x1=x2;
}); // LCOV_EXCL_START
});
2023-07-24 18:29:30 +02:00
});
2023-09-10 18:35:51 +02:00
// LCOV_EXCL_STOP
detect_reentrancy([&] {
x1.visit_all([&](arg_type&) {
x2.visit_all([&](arg_type&) {
x2=x1;
}); // LCOV_EXCL_START
});
2023-07-24 18:29:30 +02:00
});
2023-09-10 18:35:51 +02:00
// LCOV_EXCL_STOP
}
2023-07-24 18:29:30 +02:00
2023-09-10 18:35:51 +02:00
} // namespace
// clang-format off
UNORDERED_TEST(
reentrancy_tests,
((test_map)(test_node_map)(test_set)(test_node_set))
2023-09-10 18:35:51 +02:00
((value_type_generator_factory))
((default_generator)))
// clang-format on
RUN_TESTS()