Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions src/tor/TorControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -535,16 +535,28 @@ void TorControl::shutdown()

void TorControl::shutdownSync()
{

if (!hasOwnership()) {
RsWarn() << "torctrl: Ignoring shutdown command for a tor instance I don't own";
return;
}

shutdown();
while (mSocket->moretowrite(0))

// Add timeout to prevent infinite wait
int timeout_cnt = 0;
const int MAX_WAIT_ITERATIONS = 50; // 5 seconds max (50 * 100ms)

while (mSocket->moretowrite(0) && timeout_cnt < MAX_WAIT_ITERATIONS) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));

timeout_cnt++;
}

if (timeout_cnt >= MAX_WAIT_ITERATIONS) {
RsWarn() << "torctrl: Timeout waiting for socket to flush during shutdown, forcing close";
}

mSocket->close();

}

void TorControl::statusEvent(int /* code */, const ByteArray &data)
Expand Down
19 changes: 14 additions & 5 deletions src/tor/TorControlSocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ ByteArray TorControlSocket::readline(int s)

void TorControlSocket::process()
{

int empty_line_cnt = 0;
const int MAX_EMPTY_RETRIES = 20;

for (;;) {
if (!moretoread(0))
return;
Expand All @@ -134,10 +138,15 @@ void TorControlSocket::process()

if(line.empty()) // This happens when the incoming buffer isn't empty yet doesn't have a full line already.
{
if (++empty_line_cnt > MAX_EMPTY_RETRIES || shouldStop()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens here is the network is somehow stuck (due to some lag)? The TorControlSocket process will stop. I'm not sure you want that, unless there is a built-in mechanism to get it to restart when needed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It gets stuck when quitting a tor node, or occasionally even without quitting. the thread will just wait forever unless a timeout exists. it was tested again on a tor node after applying a timeout and the issue never occurred, RS will run without getting stuck

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I mispelled. I wanted to say "what happens IF the network is somehow stuck".

return; // Give up after timeout or stop request
}
std::this_thread::sleep_for(std::chrono::milliseconds(50));
continue;
}

empty_line_cnt = 0; // reset

if (!line.endsWith(ByteArray("\r\n"))) {
setError("Invalid control message syntax");
return;
Expand Down Expand Up @@ -225,12 +234,12 @@ void TorControlSocket::process()
int TorControlSocket::tick()
{
bool rw = RsTcpSocket::tick();

if(moretoread(0))
process();

if(!rw)
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // temporisation when nothing happens

return 0; // not sure about what we should return here.
std::this_thread::sleep_for(std::chrono::milliseconds(50)); // Much shorter sleep
return 0;
}