Commit e8064869 authored by Dominik Charousset's avatar Dominik Charousset

Fix segfault during test shutdown

parent e2bea08c
......@@ -35,7 +35,7 @@ public:
virtual std::unique_ptr<runnable> make(context_ptr state) = 0;
protected:
std::unique_ptr<factory> next_;
factory* next_ = nullptr;
std::string_view suite_name_;
std::string_view description_;
block_type type_;
......
......@@ -19,6 +19,12 @@ namespace caf::test {
/// A registry for our factories.
class CAF_TEST_EXPORT registry {
public:
constexpr registry() noexcept : head_(nullptr), tail_(nullptr) {
// nop
}
~registry();
/// Maps test names to factories. Elements are sorted by the order of their
/// registration.
using tests_map = unordered_flat_map<std::string_view, factory*>;
......@@ -38,21 +44,16 @@ public:
this->type_);
}
};
auto ptr = std::make_unique<impl>(suite_name, description, type);
auto result = reinterpret_cast<ptrdiff_t>(ptr.get());
if (head_ == nullptr) {
head_ = std::move(ptr);
tail_ = head_.get();
} else {
tail_->next_ = std::move(ptr);
tail_ = tail_->next_.get();
}
return result;
return instance().add(new impl(suite_name, description, type));
}
private:
static std::unique_ptr<factory> head_;
static factory* tail_;
ptrdiff_t add(factory* new_factory);
static registry& instance();
factory* head_;
factory* tail_;
};
} // namespace caf::test
......@@ -9,9 +9,18 @@
namespace caf::test {
registry::~registry() {
auto ptr = head_;
while (ptr != nullptr) {
auto next = ptr->next_;
delete ptr;
ptr = next;
}
}
registry::suites_map registry::suites() {
suites_map result;
for (auto ptr = head_.get(); ptr != nullptr; ptr = ptr->next_.get()) {
for (auto* ptr = instance().head_; ptr != nullptr; ptr = ptr->next_) {
auto& suite = result[ptr->suite_name_];
if (auto [iter, ok] = suite.emplace(ptr->description_, ptr); !ok) {
auto msg = detail::format("duplicate test name in suite {}: {}",
......@@ -22,8 +31,25 @@ registry::suites_map registry::suites() {
return result;
}
std::unique_ptr<factory> registry::head_;
ptrdiff_t registry::add(factory* new_factory) {
if (head_ == nullptr) {
head_ = new_factory;
tail_ = head_;
} else {
tail_->next_ = new_factory;
tail_ = new_factory;
}
return reinterpret_cast<ptrdiff_t>(new_factory);
}
factory* registry::tail_;
namespace {
registry default_instance;
} // namespace
registry& registry::instance() {
return default_instance;
}
} // namespace caf::test
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment