commit 594bacda9e5550c3bf4032328babccc959c54cdb Author: Tomás Touceda chiiph@torproject.org Date: Fri May 25 18:45:55 2012 -0300
Make sure there is a ReceiveWaiter in the queue before sending any control commands --- changes/raceCondition | 3 +++ src/torcontrol/ControlConnection.cpp | 13 ++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/changes/raceCondition b/changes/raceCondition new file mode 100644 index 0000000..82e4b3c --- /dev/null +++ b/changes/raceCondition @@ -0,0 +1,3 @@ + Internal cleanups and improvements: + o Make sure there is a ReceiveWaiter in the queue before issuing a + ControlCommand to avoid deadlocks in the event loop. \ No newline at end of file diff --git a/src/torcontrol/ControlConnection.cpp b/src/torcontrol/ControlConnection.cpp index 389a6e3..6497147 100644 --- a/src/torcontrol/ControlConnection.cpp +++ b/src/torcontrol/ControlConnection.cpp @@ -251,21 +251,24 @@ ControlConnection::send(const ControlCommand &cmd, bool result = false; QString errstr;
- if (send(cmd, &errstr)) { - /* Create and enqueue a new receive waiter */ - ReceiveWaiter *w = new ReceiveWaiter(); - _recvQueue.enqueue(w); + /* Preentively create and enqueue a new receive waiter */ + ReceiveWaiter *w = new ReceiveWaiter(); + _recvQueue.enqueue(w);
+ if (send(cmd, &errstr)) { /* Wait for and get the result, clean up, and return */ result = w->getResult(&reply, &errstr); + if (!result) tc::error("Failed to receive control reply: %1").arg(errstr); - delete w; } else { tc::error("Failed to send control command (%1): %2").arg(cmd.keyword()) .arg(errstr); + _recvQueue.dequeue(); }
+ delete w; + if (!result && errmsg) *errmsg = errstr; return result;
tor-commits@lists.torproject.org