Commit 5db5e3c2 authored by Matt Edman's avatar Matt Edman
Browse files

Oh, it was supposed to build?


svn:r166
parent 948219ab
Loading
Loading
Loading
Loading
+53 −0
Changes for src/control/bandwidthevent.cpp: 53 added lines, 0 removed lines.
Original line number Diff line number Diff line
/****************************************************************
*  $Id$
* 
*  Vidalia is distributed under the following license:
*
*  Copyright (C) 2006,  Matt Edman, Justin Hipple
*
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU General Public License
*  as published by the Free Software Foundation; either version 2
*  of the License, or (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin Street, Fifth Floor, 
*  Boston, MA  02110-1301, USA.
****************************************************************/

#include "eventtype.h"
#include "bandwidthevent.h"

/** Default constructor */
BandwidthEvent::BandwidthEvent(quint64 bytesRead, quint64 bytesWritten)
 : QEvent((QEvent::Type)EventType::BandwidthEvent)
{
  _bytesRead    = bytesRead;
  _bytesWritten = bytesWritten;
}

/** Default destructor */
BandwidthEvent::~BandwidthEvent()
{
}

/** Return the number of bytes read in the last second */
quint64
BandwidthEvent::bytesRead()
{
  return _bytesRead;
}

/** Returns the number of bytes written in the last second */
quint64
BandwidthEvent::bytesWritten()
{
  return _bytesWritten;
}
+49 −0
Changes for src/control/bandwidthevent.h: 49 added lines, 0 removed lines.
Original line number Diff line number Diff line
/****************************************************************
*  $Id$
* 
*  Vidalia is distributed under the following license:
*
*  Copyright (C) 2006,  Matt Edman, Justin Hipple
*
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU General Public License
*  as published by the Free Software Foundation; either version 2
*  of the License, or (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin Street, Fifth Floor, 
*  Boston, MA  02110-1301, USA.
****************************************************************/

#ifndef _BANDWIDTHEVENT_H
#define _BANDWIDTHEVENT_H

#include <QEvent>

class BandwidthEvent : public QEvent
{
public:
  /** Default constructor */
  BandwidthEvent(quint64 bytesRead, quint64 bytesWritten);
  /** Default destructor */
  ~BandwidthEvent();

  /** Returns the number of bytes read in the last second */
  quint64 bytesRead();

  /** Returns the number of bytes written in the last second */
  quint64 bytesWritten();
  
private:
  quint64 _bytesWritten;
  quint64 _bytesRead;
};

#endif
+37 −0
Changes for src/control/eventtype.h: 37 added lines, 0 removed lines.
Original line number Diff line number Diff line
/****************************************************************
*  $Id$
* 
*  Vidalia is distributed under the following license:
*
*  Copyright (C) 2006,  Matt Edman, Justin Hipple
*
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU General Public License
*  as published by the Free Software Foundation; either version 2
*  of the License, or (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin Street, Fifth Floor, 
*  Boston, MA  02110-1301, USA.
****************************************************************/

#ifndef _EVENTTYPE_H
#define _EVENTTYPE_H

#include <QEvent>

namespace EventType {
  const int BandwidthEvent = QEvent::User;
  const int CircuitEvent   = QEvent::User+1;
  const int StreamEvent    = QEvent::User+2;
  const int LogEvent       = QEvent::User+3;
}

#endif
+170 −0
Changes for src/control/messagepump.cpp: 170 added lines, 0 removed lines.
Original line number Diff line number Diff line
/****************************************************************
*  $Id$
* 
*  Vidalia is distributed under the following license:
*
*  Copyright (C) 2006,  Matt Edman, Justin Hipple
*
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU General Public License
*  as published by the Free Software Foundation; either version 2
*  of the License, or (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin Street, Fifth Floor, 
*  Boston, MA  02110-1301, USA.
****************************************************************/

#include "messagepump.h"

/** Constructor. This message pump will process messages over the given
 * ControlConnection object. */
MessagePump::MessagePump(ControlConnection *conn, TorEvents *events)
{
  _conn   = conn;
  _events = events;
}

/** Default destructor */
MessagePump::~MessagePump()
{
  if (_run) {
    stop();
  }
}

/** Starts the event processing thread */
void
MessagePump::start()
{
  _run = true;
  QThread::start();
}

/** Stops the event processing thread */
void
MessagePump::stop()
{
  /* Let the loop in run() know that we want to stop */
  _run = false;
  
  /* Fill all waiters with an empty reply */
  foreach (Waiter *w, _queue) {
    w->setReply(ControlReply());
  }

  /* If the thread is running, then wait for it to terminate */
  if (isRunning()) {
    _mutex.lock();
    _waitCond.wait(&_mutex);
    _mutex.unlock();
  }
}

/** Sends a message and waits for the response from Tor */
bool
MessagePump::send(ControlCommand cmd, ControlReply &reply, QString *errmsg)
{
  bool rc;
  _mutex.lock();
  if ((rc = _conn->sendCommand(cmd, errmsg)) == true) {
    if (_run) {
      /* Add a new waiter and add it to the queue */
      Waiter *w = new Waiter(&_mutex, &_waitCond);
      _queue.enqueue(w);
      _mutex.unlock();
  
      /* Wait for the response message */
      reply = w->getReply();
      delete w;
      return true; 
    } else {
      /* The thread isn't running, so just read the reply normally */
      _mutex.unlock();
      return _conn->readReply(reply, errmsg);
    }
  }
  _mutex.unlock();
  return false;
}

/** Implements the Tor event processing loop */
void
MessagePump::run()
{
  forever {
    /* If we're supposed to stop or the connection broke, then bail */
    if (!_run || !_conn->isConnected()) {
      break;
    }
    
    /* Check if data is waiting to be read */
    if (_conn->canReadLine()) {
      ControlReply reply;
      /* There is data on the socket, so read the reply message */
      if (_conn->readReply(reply)) {
        if (reply.getStatus() == "650") {
          /* A status of "650" means "asynchronous event notification, so
           * let's go ahead and dispatch the event. */
          _events->handleEvent(reply);
        } else {
          /* Remove the first waiter from the queue of messages awaiting a
           * response. */ 
          _mutex.lock();
          Waiter *w = _queue.dequeue();
          _mutex.unlock();
 
          /* Give it the message we just received */
          w->setReply(reply);
        }
      }
    } else {
      /* No data is on the socket, so wait a little bit and then try again */
      _conn->waitForReadyRead(250);
    }
  }
  /* Let stop() know that we're exiting now */
  _waitCond.wakeAll();
  _run = false;
}


/********************************************************************
 * MessagePump::Waiter
 */
/** Default constructor of the Waiter object */
MessagePump::Waiter::Waiter(QMutex *mutex, QWaitCondition *waitCond)
{
  _mutex = mutex;
  _waitCond = waitCond;
  _isSet = false;
}

/** Wait for the reply for this message to arrive and then return */
ControlReply
MessagePump::Waiter::getReply()
{
  while (!_isSet) {
    _mutex->lock();
    _waitCond->wait(_mutex);
    _mutex->unlock();
  }
  return _reply;
}

/** The reply for this message has arrived. Set the proper member variable and
 * then signal to wake up the waiting thread. */
void
MessagePump::Waiter::setReply(ControlReply reply)
{
  _reply = reply;
  _isSet = true;
  _waitCond->wakeAll();
}
+85 −0
Changes for src/control/messagepump.h: 85 added lines, 0 removed lines.
Original line number Diff line number Diff line
/****************************************************************
*  $Id$
* 
*  Vidalia is distributed under the following license:
*
*  Copyright (C) 2006,  Matt Edman, Justin Hipple
*
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU General Public License
*  as published by the Free Software Foundation; either version 2
*  of the License, or (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin Street, Fifth Floor, 
*  Boston, MA  02110-1301, USA.
****************************************************************/

#ifndef _EVENTPUMP_H
#define _EVENTPUMP_H

#include <QThread>
#include <QMutex>
#include <QWaitCondition>
#include <QQueue>

#include "controlconnection.h"
#include "torevents.h"

class MessagePump : public QThread
{
public:
  MessagePump(ControlConnection *conn, TorEvents *events);
  ~MessagePump();
  
  /** Start the event processing thread */
  void start();
  /** Stop the event processing thread */
  void stop();

  /** Sends a control command and waits for the reply */
  bool send(ControlCommand cmd, ControlReply &reply, QString *errmsg = 0);


private:
  /** Pointer to a previously constructed control conn */
  ControlConnection *_conn;
  /** Pointer to a previously constructed TorEvents list of event handlers */
  TorEvents *_events;
  /** Set to true while the event loop is running */
  bool _run; 
  /** Lock around the waiting message queue */
  QMutex _mutex;
  /** A wait condition that awakens threads when a non-event messag arrives */
  QWaitCondition _waitCond;

  /** Implements the event processing loop that runs in a separate thread */
  void run();
 
  /** This class uses the same producer/consumer model in the Java control
   * library povided with Tor */
  class Waiter
  {
    public:
      Waiter(QMutex *mutex, QWaitCondition *waitCond);
      ControlReply getReply();
      void setReply(ControlReply reply);

    private:
      bool _isSet;
      QMutex *_mutex;
      QWaitCondition *_waitCond;
      ControlReply _reply;
  };
  /** A queue of messages waiting for a response */
  QQueue<Waiter*> _queue;
};

#endif