Skip to content

Commit

Permalink
fix: avoids deadlock when requesting info on disconnected inlet
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
noah-roberts committed Apr 25, 2024
1 parent 6a85d6f commit 7bd4406
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/info_receiver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ void lsl::info_receiver::info_thread() {
buffer.register_at(&conn_);
std::iostream server_stream(&buffer);
// connect...
buffer.connect(conn_.get_tcp_endpoint());
if (nullptr == buffer.connect(conn_.get_tcp_endpoint()))
{
throw asio::system_error(buffer.error());
}
// send the query
server_stream << "LSL:fullinfo\r\n" << std::flush;
// receive and parse the response
Expand Down
16 changes: 16 additions & 0 deletions testing/ext/discovery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,21 @@ TEST_CASE("fullinfo", "[inlet][fullinfo][basic]") {
CHECK(fullinfo.desc().child_value("info") == extinfo);
}

TEST_CASE("downed outlet deadlock", "[inlet][streaminfo]")
{
// This test verifies that calling info on a resolved inlet that has become disconnected
// does not get locked waiting on a response.
auto outlet = std::make_unique<lsl::stream_outlet>(lsl::stream_info("deadtest", "type"));

auto resolved = lsl::resolve_streams();
REQUIRE(!resolved.empty());
lsl::stream_inlet inlet(resolved[0]);

outlet.reset();

// this would previously deadlock
CHECK_THROWS(inlet.info());
}


} // namespace

0 comments on commit 7bd4406

Please sign in to comment.