[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