Skip to content

Commit a9da358

Browse files
noah-robertscboulay
authored andcommitted
fix: avoids deadlock when requesting info on disconnected inlet
* Adds test to for calling info on a disconnected stream_inlet to testing/ext/discovery.cpp * Fixes deadlock that occurred by checking return value of buffer.connect and throwing a system_error based on the error_code in buffer if the check fails. issue: #201
1 parent fdff878 commit a9da358

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

src/info_receiver.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,10 @@ void lsl::info_receiver::info_thread() {
5252
buffer.register_at(&conn_);
5353
std::iostream server_stream(&buffer);
5454
// connect...
55-
buffer.connect(conn_.get_tcp_endpoint());
55+
if (nullptr == buffer.connect(conn_.get_tcp_endpoint()))
56+
{
57+
throw asio::system_error(buffer.error());
58+
}
5659
// send the query
5760
server_stream << "LSL:fullinfo\r\n" << std::flush;
5861
// receive and parse the response

testing/ext/discovery.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,21 @@ TEST_CASE("fullinfo", "[inlet][fullinfo][basic]") {
4343
CHECK(fullinfo.desc().child_value("info") == extinfo);
4444
}
4545

46+
TEST_CASE("downed outlet deadlock", "[inlet][streaminfo]")
47+
{
48+
// This test verifies that calling info on a resolved inlet that has become disconnected
49+
// does not get locked waiting on a response.
50+
auto outlet = std::make_unique<lsl::stream_outlet>(lsl::stream_info("deadtest", "type"));
51+
52+
auto resolved = lsl::resolve_streams();
53+
REQUIRE(!resolved.empty());
54+
lsl::stream_inlet inlet(resolved[0]);
55+
56+
outlet.reset();
57+
58+
// this would previously deadlock
59+
CHECK_THROWS(inlet.info());
60+
}
61+
4662

4763
} // namespace

0 commit comments

Comments
 (0)