From 961eca52761a31a0200c567b44e2b2d6d6e50df3 Mon Sep 17 00:00:00 2001 From: Dennis Klein Date: Fri, 10 Nov 2023 12:45:17 +0100 Subject: [PATCH] test(PluginServices): state change subscription thread-safety --- test/plugin_services/_control.cxx | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/test/plugin_services/_control.cxx b/test/plugin_services/_control.cxx index 222f73061..498c44a81 100644 --- a/test/plugin_services/_control.cxx +++ b/test/plugin_services/_control.cxx @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * + * Copyright (C) 2017-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * * * This software is distributed under the terms of the * * GNU Lesser General Public Licence (LGPL) version 3, * @@ -7,8 +7,12 @@ ********************************************************************************/ #include "Fixture.h" +#include #include +#include +#include #include +#include namespace { @@ -142,4 +146,27 @@ TEST_F(PluginServices, ControlStateTransitionConversions) EXPECT_NO_THROW(mServices.ToStr(DeviceStateTransition::ErrorFound)); } +TEST_F(PluginServices, SubscriptionThreadSafety) +{ + // obviously not a perfect test, but I could segfault fmq reliably with it (without the fix) + + constexpr auto attempts = 1000; + constexpr auto subscribers = 5; + + std::array, subscribers> threads; + auto id = 0; + for (auto& thread : threads) { + thread = std::make_unique([&](){ + auto const subscriber = fair::mq::tools::ToString("subscriber_", id); + for (auto i = 0; i < attempts; ++i) { + mServices.SubscribeToDeviceStateChange(subscriber, [](DeviceState){}); + mServices.UnsubscribeFromDeviceStateChange(subscriber); + } + }); + ++id; + } + + for (auto& thread : threads) { thread->join(); } +} + } /* namespace */