Browse Source

- Implemented asynchronous hostname resolution in Peer list

adaptive-webui-19844
Christophe Dumez 15 years ago
parent
commit
f7c196dbcf
  1. 21
      src/peerlistwidget.cpp
  2. 17
      src/peerlistwidget.h
  3. 138
      src/reverseresolution.h
  4. 3
      src/src.pro

21
src/peerlistwidget.cpp

@ -30,7 +30,7 @@
#include "peerlistwidget.h" #include "peerlistwidget.h"
#include "peerlistdelegate.h" #include "peerlistdelegate.h"
#include "misc.h" #include "reverseresolution.h"
#include <QStandardItemModel> #include <QStandardItemModel>
#include <QSortFilterProxyModel> #include <QSortFilterProxyModel>
#include <QSet> #include <QSet>
@ -60,12 +60,17 @@ PeerListWidget::PeerListWidget() {
setItemDelegate(listDelegate); setItemDelegate(listDelegate);
// Enable sorting // Enable sorting
setSortingEnabled(true); setSortingEnabled(true);
// IP to Hostname resolver
resolver = new ReverseResolution(this);
connect(resolver, SIGNAL(ip_resolved(QString,QString)), this, SLOT(handleResolved(QString,QString)));
resolver->start();
} }
PeerListWidget::~PeerListWidget() { PeerListWidget::~PeerListWidget() {
delete proxyModel; delete proxyModel;
delete listModel; delete listModel;
delete listDelegate; delete listDelegate;
delete resolver;
} }
void PeerListWidget::loadPeers(QTorrentHandle &h) { void PeerListWidget::loadPeers(QTorrentHandle &h) {
@ -98,19 +103,19 @@ QStandardItem* PeerListWidget::addPeer(QString ip, peer_info peer) {
// Adding Peer to peer list // Adding Peer to peer list
listModel->insertRow(row); listModel->insertRow(row);
listModel->setData(listModel->index(row, IP), ip); listModel->setData(listModel->index(row, IP), ip);
resolver->resolve(peer.ip);
listModel->setData(listModel->index(row, CLIENT), misc::toQString(peer.client)); listModel->setData(listModel->index(row, CLIENT), misc::toQString(peer.client));
listModel->setData(listModel->index(row, PROGRESS), peer.progress); listModel->setData(listModel->index(row, PROGRESS), peer.progress);
listModel->setData(listModel->index(row, DOWN_SPEED), peer.payload_down_speed); listModel->setData(listModel->index(row, DOWN_SPEED), peer.payload_down_speed);
listModel->setData(listModel->index(row, UP_SPEED), peer.payload_up_speed); listModel->setData(listModel->index(row, UP_SPEED), peer.payload_up_speed);
listModel->setData(listModel->index(row, TOT_DOWN), peer.total_download); listModel->setData(listModel->index(row, TOT_DOWN), peer.total_download);
listModel->setData(listModel->index(row, TOT_UP), peer.total_upload); listModel->setData(listModel->index(row, TOT_UP), peer.total_upload);
return listModel->item(row, 0); return listModel->item(row, IP);
} }
void PeerListWidget::updatePeer(QString ip, peer_info peer) { void PeerListWidget::updatePeer(QString ip, peer_info peer) {
QStandardItem *item = peerItems.value(ip); QStandardItem *item = peerItems.value(ip);
int row = item->row(); int row = item->row();
listModel->setData(listModel->index(row, IP), ip);
listModel->setData(listModel->index(row, CLIENT), misc::toQString(peer.client)); listModel->setData(listModel->index(row, CLIENT), misc::toQString(peer.client));
listModel->setData(listModel->index(row, PROGRESS), peer.progress); listModel->setData(listModel->index(row, PROGRESS), peer.progress);
listModel->setData(listModel->index(row, DOWN_SPEED), peer.payload_down_speed); listModel->setData(listModel->index(row, DOWN_SPEED), peer.payload_down_speed);
@ -118,3 +123,13 @@ void PeerListWidget::updatePeer(QString ip, peer_info peer) {
listModel->setData(listModel->index(row, TOT_DOWN), peer.total_download); listModel->setData(listModel->index(row, TOT_DOWN), peer.total_download);
listModel->setData(listModel->index(row, TOT_UP), peer.total_upload); listModel->setData(listModel->index(row, TOT_UP), peer.total_upload);
} }
void PeerListWidget::handleResolved(QString ip, QString hostname) {
qDebug("%s was resolved to %s", ip.toLocal8Bit().data(), hostname.toLocal8Bit().data());
QStandardItem *item = peerItems.value(ip, 0);
if(item) {
qDebug("item was updated");
//item->setData(hostname);
listModel->setData(listModel->indexFromItem(item), hostname);
}
}

17
src/peerlistwidget.h

@ -34,28 +34,33 @@
#include <QTreeView> #include <QTreeView>
#include <QHash> #include <QHash>
#include "qtorrenthandle.h" #include "qtorrenthandle.h"
#include "misc.h"
class QStandardItemModel; class QStandardItemModel;
class QStandardItem; class QStandardItem;
class QSortFilterProxyModel; class QSortFilterProxyModel;
class PeerListDelegate; class PeerListDelegate;
class ReverseResolution;
class PeerListWidget : public QTreeView { class PeerListWidget : public QTreeView {
Q_OBJECT
private: private:
QStandardItemModel *listModel; QStandardItemModel *listModel;
PeerListDelegate *listDelegate; PeerListDelegate *listDelegate;
QSortFilterProxyModel * proxyModel; QSortFilterProxyModel * proxyModel;
QHash<QString, QStandardItem*> peerItems; QHash<QString, QStandardItem*> peerItems;
ReverseResolution *resolver;
public: public:
PeerListWidget(); PeerListWidget();
~PeerListWidget(); ~PeerListWidget();
public slots: public slots:
void loadPeers(QTorrentHandle &h); void loadPeers(QTorrentHandle &h);
QStandardItem* addPeer(QString ip, peer_info peer); QStandardItem* addPeer(QString ip, peer_info peer);
void updatePeer(QString ip, peer_info peer); void updatePeer(QString ip, peer_info peer);
void handleResolved(QString ip, QString hostname);
}; };
#endif // PEERLISTWIDGET_H #endif // PEERLISTWIDGET_H

138
src/reverseresolution.h

@ -0,0 +1,138 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2006 Christophe Dumez
*
* 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.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
#ifndef REVERSERESOLUTION_H
#define REVERSERESOLUTION_H
#include <QQueue>
#include <QThread>
#include <QWaitCondition>
#include <QMutex>
#include <QList>
#include <boost/asio/ip/tcp.hpp>
#include "misc.h"
#define MAX_THREADS 20
class ReverseResolutionST: public QThread {
Q_OBJECT
private:
boost::asio::ip::tcp::endpoint ip;
boost::asio::ip::tcp::resolver resolver;
public:
ReverseResolutionST(boost::asio::io_service &ios, QObject *parent=0): QThread(parent), resolver(ios) {
}
~ReverseResolutionST() {
wait();
}
void setIP(boost::asio::ip::tcp::endpoint &_ip) {
ip = _ip;
}
signals:
void ip_resolved(QString ip, QString hostname);
protected:
void run() {
boost::asio::ip::tcp::resolver::iterator it = resolver.resolve(ip);
qDebug("IP was resolved");
boost::asio::ip::tcp::endpoint endpoint = *it;
emit ip_resolved(misc::toQString(endpoint.address().to_string()), misc::toQString((*it).host_name()));
}
};
class ReverseResolution: public QThread {
Q_OBJECT
private:
QQueue<boost::asio::ip::tcp::endpoint> ips;
QMutex mut;
QWaitCondition cond;
bool stopped;
boost::asio::io_service ios;
QList<ReverseResolutionST*> subThreads;
public:
ReverseResolution(QObject* parent): QThread(parent), stopped(false) {
}
~ReverseResolution() {
stopped = true;
cond.wakeOne();
qDeleteAll(subThreads);
wait();
}
void resolve(boost::asio::ip::tcp::endpoint ip) {
mut.lock();
ips.enqueue(ip);
if(subThreads.size() < MAX_THREADS)
cond.wakeOne();
mut.unlock();
}
signals:
void ip_resolved(QString ip, QString hostname);
protected slots:
void forwardSignal(QString ip, QString hostname) {
emit ip_resolved(ip, hostname);
mut.lock();
subThreads.removeOne(static_cast<ReverseResolutionST*>(sender()));
if(!ips.empty())
cond.wakeOne();
mut.unlock();
sender()->deleteLater();
}
protected:
void run() {
do {
mut.lock();
cond.wait(&mut);
if(stopped) return;
boost::asio::ip::tcp::endpoint ip = ips.dequeue();
ReverseResolutionST *st = new ReverseResolutionST(ios);
subThreads.append(st);
mut.unlock();
connect(st, SIGNAL(ip_resolved(QString,QString)), this, SLOT(forwardSignal(QString,QString)));
st->setIP(ip);
st->start();
}while(!stopped);
}
};
#endif // REVERSERESOLUTION_H

3
src/src.pro

@ -187,7 +187,8 @@ HEADERS += GUI.h \
TorrentFilesModel.h \ TorrentFilesModel.h \
filesystemwatcher.h \ filesystemwatcher.h \
peerlistwidget.h \ peerlistwidget.h \
peerlistdelegate.h peerlistdelegate.h \
reverseresolution.h
FORMS += MainWindow.ui \ FORMS += MainWindow.ui \
options.ui \ options.ui \
about.ui \ about.ui \

Loading…
Cancel
Save