commit 6205ea37dc834390f4a21be8ad75939e7827064a Author: Sebastian Baginski sebthestampede@gmail.com Date: Sat May 26 13:17:16 2012 +0200
fix for possible infinite loop in ControlConnection --- changes/bug5519 | 3 +++ src/torcontrol/ControlConnection.cpp | 31 ++++++++++++++++++++----------- src/torcontrol/ControlConnection.h | 2 ++ 3 files changed, 25 insertions(+), 11 deletions(-)
diff --git a/changes/bug5519 b/changes/bug5519 new file mode 100644 index 0000000..461fd6b --- /dev/null +++ b/changes/bug5519 @@ -0,0 +1,3 @@ + Internal cleanups and improvements: + o Fix possible infinite loop in ControlConnection + object. Fixes bug 5519. diff --git a/src/torcontrol/ControlConnection.cpp b/src/torcontrol/ControlConnection.cpp index 389a6e3..8141733 100644 --- a/src/torcontrol/ControlConnection.cpp +++ b/src/torcontrol/ControlConnection.cpp @@ -112,17 +112,7 @@ ControlConnection::connect() void ControlConnection::disconnect() { - /** If there are any messages waiting for a response, clear them. */ - if (_sendWaiter->status() == SendCommandEvent::SendWaiter::Waiting) - _sendWaiter->setResult(false, tr("Control socket is not connected.")); - - while (!_recvQueue.isEmpty()) { - ReceiveWaiter *w = _recvQueue.dequeue(); - w->setResult(false, ControlReply(), - tr("Control socket is not connected.")); - - QCoreApplication::processEvents(QEventLoop::AllEvents, 1000); - } + clearCommandQueue();
setStatus(Disconnecting);
@@ -140,6 +130,23 @@ ControlConnection::disconnect() _sock->disconnect(this); }
+/** Clears all waiting commands. */ +void +ControlConnection::clearCommandQueue() +{ + /** If there are any messages waiting for a response, clear them. */ + if (_sendWaiter->status() == SendCommandEvent::SendWaiter::Waiting) + _sendWaiter->setResult(false, tr("Control socket is not connected.")); + + while (!_recvQueue.isEmpty()) { + ReceiveWaiter *w = _recvQueue.dequeue(); + w->setResult(false, ControlReply(), + tr("Control socket is not connected.")); + + QCoreApplication::processEvents(QEventLoop::AllEvents, 1000); + } +} + /** Called when the control socket is connected. This method checks that the * control protocol version of the Tor we connected to is at least V1. */ void @@ -241,6 +248,8 @@ ControlConnection::setStatus(Status status) .arg(statusString(_status)) .arg(statusString(status)); _status = status; + if (_status == Disconnected) + clearCommandQueue(); }
/** Sends a control command to Tor and waits for the reply. */ diff --git a/src/torcontrol/ControlConnection.h b/src/torcontrol/ControlConnection.h index 0ce8940..8bd9020 100644 --- a/src/torcontrol/ControlConnection.h +++ b/src/torcontrol/ControlConnection.h @@ -90,6 +90,8 @@ private: void setStatus(Status status); /** Returns the string description of <b>status</b>. */ QString statusString(Status status); + /** Clears all waiting commands. */ + void clearCommandQueue(); /** Main thread implementation. */ void run();
tor-commits@lists.torproject.org