[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[vidalia-svn] r2588: Merge r2580, r2581, and r2583 to the upnp branch so I can te (in vidalia: . branches/upnp/src/torcontrol)
Author: edmanm
Date: 2008-05-19 23:03:14 -0400 (Mon, 19 May 2008)
New Revision: 2588
Modified:
vidalia/
vidalia/branches/upnp/src/torcontrol/controlconnection.cpp
vidalia/branches/upnp/src/torcontrol/controlconnection.h
Log:
r335@thebe: edmanm | 2008-05-19 23:03:54 -0400
Merge r2580, r2581, and r2583 to the upnp branch so I can test my changes with
Qt 4.4.
Property changes on: vidalia
___________________________________________________________________
svk:merge ticket from /local/vidalia [r335] on 45a62a8a-8088-484c-baad-c7b3e776dd32
Modified: vidalia/branches/upnp/src/torcontrol/controlconnection.cpp
===================================================================
--- vidalia/branches/upnp/src/torcontrol/controlconnection.cpp 2008-05-20 02:44:46 UTC (rev 2587)
+++ vidalia/branches/upnp/src/torcontrol/controlconnection.cpp 2008-05-20 03:03:14 UTC (rev 2588)
@@ -46,7 +46,7 @@
/** Connect to the specified Tor control interface. */
void
-ControlConnection::connect(QHostAddress addr, quint16 port)
+ControlConnection::connect(const QHostAddress &addr, quint16 port)
{
if (isRunning()) {
tc::error("Bug: Tried to call ControlConnection::connect() when the "
@@ -196,69 +196,48 @@
/** Sends a control command to Tor and waits for the reply. */
bool
-ControlConnection::send(ControlCommand cmd, ControlReply &reply, QString *errmsg)
+ControlConnection::send(const ControlCommand &cmd,
+ ControlReply &reply, QString *errmsg)
{
+ ReceiveWaiter w;
bool result = false;
QString errstr;
-
- _recvMutex.lock();
- if (send(cmd, &errstr)) {
+
+ _connMutex.lock();
+ if (!_sock) {
+ _connMutex.unlock();
+ return err(errmsg, tr("Control socket is not connected."));
+ }
+ if (_sock->sendCommand(cmd, &errstr)) {
/* Create and enqueue a new receive waiter */
- ReceiveWaiter *w = new ReceiveWaiter();
- _recvQueue.enqueue(w);
- _recvMutex.unlock();
-
- /* 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;
+ _recvQueue.enqueue(&w);
+ _connMutex.unlock();
} else {
+ _connMutex.unlock();
tc::error("Failed to send control command (%1): %2").arg(cmd.keyword())
.arg(errstr);
- _recvMutex.unlock();
+ return err(errmsg, errstr);
}
- if (!result && errmsg)
- *errmsg = 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);
+ if (errmsg)
+ *errmsg = errstr;
+ }
return result;
}
-/** Sends a control command to Tor. If the current thread is not the thread
- * that actually owns the socket, the command will be pushed to the correct
- * thread before sending. */
+/** Sends a control command to Tor and returns without waiting for the
+ * response. */
bool
-ControlConnection::send(ControlCommand cmd, QString *errmsg)
+ControlConnection::send(const ControlCommand &cmd, QString *errmsg)
{
- QThread *socketThread;
- bool result;
-
- /* Check for a valid and connected socket */
- _connMutex.lock();
- if (!_sock || _status != Connected) {
- tc::warn("Unable to send control command '%1' when socket status is '%2'")
- .arg(cmd.keyword()).arg(_status);
- _connMutex.unlock();
- return err(errmsg, tr("Control socket is not connected."));
- }
- socketThread = _sock->thread();
- _connMutex.unlock();
-
- if (socketThread != QThread::currentThread()) {
- /* Push the message to the correct thread before sending */
- SendWaiter *w = new SendWaiter();
- QCoreApplication::postEvent(_sock, new SendCommandEvent(cmd, w));
-
- /* Wait for the result, clean up, and return */
- result = w->getResult(errmsg);
- delete w;
- } else {
- /* Send the command directly on the socket */
- _connMutex.lock();
- result = _sock->sendCommand(cmd, errmsg);
- _connMutex.unlock();
- }
- return result;
+ QMutexLocker locker(&_connMutex);
+ if (!_sock)
+ return err(errmsg, tr("Control socket is not connected."));
+ return _sock->sendCommand(cmd, errmsg);
}
/** Called when there is data on the control socket. */
@@ -283,12 +262,10 @@
/* Response to a previous command */
tc::debug("Control Reply: %1").arg(reply.toString());
- _recvMutex.lock();
if (!_recvQueue.isEmpty()) {
waiter = _recvQueue.dequeue();
waiter->setResult(true, reply);
}
- _recvMutex.unlock();
}
} else {
tc::error("Unable to read control reply: %1").arg(errmsg);
@@ -296,40 +273,6 @@
}
}
-/** Catches events for the control socket. */
-bool
-ControlConnection::eventFilter(QObject *obj, QEvent *event)
-{
- if (event->type() == CustomEventType::SendCommandEvent) {
- /* Get the control command and waiter from the event */
- SendCommandEvent *sce = (SendCommandEvent *)event;
- SendWaiter *w = sce->waiter();
- QString errmsg;
- bool result;
-
- /* Send the command, if the socket exists. */
- _connMutex.lock();
- if (_sock) {
- result = _sock->sendCommand(sce->command(), &errmsg);
- } else {
- result = false;
- errmsg = tr("Control socket is not connected");
- }
- _connMutex.unlock();
-
- /* If there is someone waiting for a result, give them one. */
- if (w) {
- w->setResult(result, errmsg);
- }
-
- /* Stop processing this event */
- sce->accept();
- return true;
- }
- /* Pass other events on */
- return QObject::eventFilter(obj, event);
-}
-
/** Main thread implementation. Creates and connects a control socket, then
* spins up an event loop. */
void
@@ -353,7 +296,6 @@
QObject::connect(_connectTimer, SIGNAL(timeout()), this, SLOT(connect()),
Qt::DirectConnection);
- _sock->installEventFilter(this);
_connMutex.unlock();
/* Attempt to connect to Tor */
@@ -364,21 +306,18 @@
/* Clean up the socket */
_connMutex.lock();
- _sock->removeEventFilter(this);
_sock->disconnect(this);
delete _sock;
delete _connectTimer;
_sock = 0;
- _connMutex.unlock();
/* If there are any messages waiting for a response, clear them. */
- _recvMutex.lock();
while (!_recvQueue.isEmpty()) {
ReceiveWaiter *w = _recvQueue.dequeue();
w->setResult(false, ControlReply(),
tr("Control socket is not connected."));
}
- _recvMutex.unlock();
+ _connMutex.unlock();
}
@@ -410,8 +349,8 @@
/** Sets the result and reply from a control command. */
void
ControlConnection::ReceiveWaiter::setResult(bool success,
- ControlReply reply,
- QString errmsg)
+ const ControlReply &reply,
+ const QString &errmsg)
{
_mutex.lock();
_status = (success ? Success : Failed);
@@ -421,38 +360,3 @@
_waitCond.wakeAll();
}
-
-/*
- * ControlConnection::SendWaiter
- */
-/** Sets the result of the send operation. */
-void
-ControlConnection::SendWaiter::setResult(bool success, QString errmsg)
-{
- _mutex.lock();
- _status = (success ? Success : Failed);
- _errmsg = errmsg;
- _mutex.unlock();
- _waitCond.wakeAll();
-}
-
-/** Waits for and gets the result of the send operation. */
-bool
-ControlConnection::SendWaiter::getResult(QString *errmsg)
-{
- forever {
- _mutex.lock();
- if (_status == Waiting) {
- _waitCond.wait(&_mutex);
- _mutex.unlock();
- } else {
- _mutex.unlock();
- break;
- }
- }
- if (errmsg) {
- *errmsg = _errmsg;
- }
- return (_status == Success);
-}
-
Modified: vidalia/branches/upnp/src/torcontrol/controlconnection.h
===================================================================
--- vidalia/branches/upnp/src/torcontrol/controlconnection.h 2008-05-20 02:44:46 UTC (rev 2587)
+++ vidalia/branches/upnp/src/torcontrol/controlconnection.h 2008-05-20 03:03:14 UTC (rev 2588)
@@ -50,7 +50,7 @@
~ControlConnection();
/** Connect to the specified Tor control interface. */
- void connect(QHostAddress addr, quint16 port);
+ void connect(const QHostAddress &addr, quint16 port);
/** Cancels a pending control connection to Tor. */
void cancelConnect();
/** Disconnect from Tor's control interface. */
@@ -60,9 +60,9 @@
/** Returns the status of the control connection. */
Status status();
/** Sends a control command to Tor and waits for the reply. */
- bool send(ControlCommand cmd, ControlReply &reply, QString *errmsg = 0);
+ bool send(const ControlCommand &cmd, ControlReply &reply, QString *errmsg = 0);
/** Sends a control command to Tor and does not wait for a reply. */
- bool send(ControlCommand cmd, QString *errmsg = 0);
+ bool send(const ControlCommand &cmd, QString *errmsg = 0);
signals:
/** Emitted when a control connection has been established. */
@@ -72,10 +72,6 @@
/** Emitted when a control connection fails. */
void connectFailed(QString errmsg);
-protected:
- /** Catches events for the control socket. */
- bool eventFilter(QObject *obj, QEvent *event);
-
private slots:
/** Connects to Tor's control interface. */
void connect();
@@ -102,7 +98,6 @@
QHostAddress _addr; /**< Address of Tor's control interface. */
quint16 _port; /**< Port of Tor's control interface. */
QMutex _connMutex; /**< Mutex around the control socket. */
- QMutex _recvMutex; /**< Mutex around the queue of ReceiveWaiters. */
QMutex _statusMutex; /**< Mutex around the connection status value. */
int _connectAttempt; /**< How many times we've tried to connect to Tor while
waiting for Tor to start. */
@@ -116,8 +111,8 @@
/** Waits for and gets the reply from a control command. */
bool getResult(ControlReply *reply, QString *errmsg = 0);
/** Sets the result and reply from a control command. */
- void setResult(bool success, ControlReply reply,
- QString errmsg = QString());
+ void setResult(bool success, const ControlReply &reply,
+ const QString &errmsg = QString());
private:
/** Status of the receive waiter. */
enum ReceiveStatus { Waiting, Failed, Success } _status;
@@ -127,39 +122,6 @@
QString _errmsg; /**< Error message if the reply fails. */
};
QQueue<ReceiveWaiter *> _recvQueue; /**< Objects waiting for a reply. */
-
- /** Object used to wait for the result of a send operation. */
- class SendWaiter {
- public:
- /** Default constructor. */
- SendWaiter() { _status = Waiting; }
- /** Sets the result of the send operation. */
- void setResult(bool success, QString errmsg = QString());
- /** Waits for and gets the result of the send operation. */
- bool getResult(QString *errmsg = 0);
- private:
- /** Status of the send waiter. */
- enum SenderStatus { Waiting, Failed, Success } _status;
- QMutex _mutex; /**< Mutex around the wait condition. */
- QWaitCondition _waitCond; /**< Waits for the send to complete. */
- QString _errmsg; /**< Error message if the send fails. */
- };
-
- /** Private event used to push a control command to the socket's thread */
- class SendCommandEvent : public QEvent {
- public:
- /** Constructor. */
- SendCommandEvent(ControlCommand cmd, SendWaiter *waiter = 0)
- : QEvent((QEvent::Type)CustomEventType::SendCommandEvent)
- { _cmd = cmd; _waiter = waiter; }
- /** Returns the control command to send to Tor. */
- ControlCommand command() { return _cmd; }
- /** Returns a waiter (if any) for the result of this send. */
- SendWaiter* waiter() { return _waiter; }
- private:
- ControlCommand _cmd; /**< Command to send to Tor. */
- SendWaiter* _waiter; /**< Waiter for the result of this event. */
- };
};
#endif