Skip to content

Commit d7a2cc8

Browse files
committed
Fixed possible infinite loop in Groot2Publisher when destructor is called
1 parent 8b79f96 commit d7a2cc8

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

src/loggers/groot2_publisher.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ struct Groot2Publisher::PImpl
8181

8282
std::string tree_xml;
8383

84-
std::atomic_bool active_server = false;
84+
std::atomic_bool active_server = true;
8585
std::thread server_thread;
8686

8787
std::mutex status_mutex;
@@ -241,7 +241,6 @@ void Groot2Publisher::serverLoop()
241241
{
242242
auto const serialized_uuid = CreateRandomUUID();
243243

244-
_p->active_server = true;
245244
auto& socket = _p->server;
246245

247246
auto sendErrorReply = [&socket](const std::string& msg) {

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ set(BT_TESTS
1212
gtest_enums.cpp
1313
gtest_factory.cpp
1414
gtest_fallback.cpp
15+
gtest_groot2_publisher.cpp
1516
gtest_parallel.cpp
1617
gtest_preconditions.cpp
1718
gtest_ports.cpp

tests/gtest_groot2_publisher.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include <chrono>
2+
#include <future>
3+
4+
#include <behaviortree_cpp/loggers/groot2_protocol.h>
5+
#include <behaviortree_cpp/loggers/groot2_publisher.h>
6+
#include <gtest/gtest.h>
7+
8+
using namespace std::chrono_literals;
9+
10+
namespace
11+
{
12+
static const char* xml_text = R"(
13+
<root BTCPP_format="4">
14+
<BehaviorTree ID="MainTree">
15+
<ThrowRuntimeError/>
16+
</BehaviorTree>
17+
</root>
18+
)";
19+
20+
void throwRuntimeError()
21+
{
22+
BT::BehaviorTreeFactory factory;
23+
factory.registerSimpleAction("ThrowRuntimeError", [](BT::TreeNode&) {
24+
throw BT::RuntimeError("Oops!");
25+
return BT::NodeStatus::FAILURE;
26+
});
27+
28+
auto tree = factory.createTreeFromText(xml_text);
29+
BT::Groot2Publisher publisher(tree);
30+
EXPECT_THROW(tree.tickOnce(), BT::RuntimeError);
31+
}
32+
} // namespace
33+
34+
TEST(Groot2PublisherTest, EnsureNoInfiniteLoopOnThrow)
35+
{
36+
auto fut = std::async(std::launch::async, throwRuntimeError);
37+
auto status = fut.wait_for(1s);
38+
if(status != std::future_status::ready)
39+
{
40+
ADD_FAILURE() << "Function did not finish (possible infinite loop)";
41+
std::terminate(); // Force exit to avoid destructor blocking
42+
}
43+
}

0 commit comments

Comments
 (0)