Skip to content

Commit ce7f1e9

Browse files
authored
stop producer on destruction (UniversalRobots#472)
When a TCP socket silently fails (e.g. network loss, cable pull) — where no RST or FIN is delivered — RTDEClient::~RTDEClient() hangs indefinitely. The background read thread is inside tryGetImpl's inner while(true) loop. stream_.read() returns EAGAIN every ~1 second due to the SO_RCVTIMEO set in setupProducer, but: - !running_ is false (the producer was never stopped) - stream_.getState() == SocketState::Connected is true (the kernel still considers the socket connected — no RST was received) So the loop hits continue and spins indefinitely. When stopBackgroundRead() is then called in the destructor, it sets background_read_running_ = false and calls join(). But background_read_running_ is only checked in the outer loop of backgroundReadThreadFunc — the thread is trapped inside tryGetImpl where only running_ (the URProducer flag) controls exit. The join() never returns. The fix is to call prod_->stopProducer() before stopBackgroundRead(). This sets running_ = false, so within at most one SO_RCVTIMEO interval (~1 second), tryGetImpl sees !running_ and returns, the background thread exits its outer loop, and the join() completes immediately. Note that disconnect() already does this correctly (stream_.disconnect() + prod_->stopProducer() + stopBackgroundRead()), but in the destructor stopBackgroundRead() is called before disconnect(), so the producer is never stopped before the join is attempted.
1 parent bd19a47 commit ce7f1e9

1 file changed

Lines changed: 1 addition & 0 deletions

File tree

src/rtde/rtde_client.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ RTDEClient::~RTDEClient()
9191
{
9292
reconnecting_thread_.join();
9393
}
94+
prod_->stopProducer();
9495
stopBackgroundRead();
9596
disconnect();
9697
}

0 commit comments

Comments
 (0)