Browse Source

Merge pull request #2022 from sorokin/for-sledgehammer

a small optimization, a micro optimization and a fix
adaptive-webui-19844
sledgehammer999 10 years ago
parent
commit
f50eac4c15
  1. 52
      src/qtlibtorrent/alertdispatcher.cpp
  2. 13
      src/qtlibtorrent/alertdispatcher.h
  3. 6
      src/qtlibtorrent/qbtsession.cpp
  4. 2
      src/qtlibtorrent/torrentmodel.cpp

52
src/qtlibtorrent/alertdispatcher.cpp

@ -33,12 +33,26 @@
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <QMutexLocker> #include <QMutexLocker>
const size_t DEFAULT_ALERTS_CAPACITY = 32;
struct QAlertDispatcher::Tag {
Tag(QAlertDispatcher* dispatcher);
QAlertDispatcher* dispatcher;
QMutex alerts_mutex;
};
QAlertDispatcher::Tag::Tag(QAlertDispatcher* dispatcher)
: dispatcher(dispatcher)
{}
QAlertDispatcher::QAlertDispatcher(libtorrent::session *session, QObject* parent) QAlertDispatcher::QAlertDispatcher(libtorrent::session *session, QObject* parent)
: QObject(parent) : QObject(parent)
, m_session(session) , m_session(session)
, current_tag(new QAtomicPointer<QAlertDispatcher>(this)) , current_tag(new Tag(this))
, event_posted(false) , event_posted(false)
{ {
alerts.reserve(DEFAULT_ALERTS_CAPACITY);
m_session->set_alert_dispatch(boost::bind(&QAlertDispatcher::dispatch, current_tag, _1)); m_session->set_alert_dispatch(boost::bind(&QAlertDispatcher::dispatch, current_tag, _1));
} }
@ -51,8 +65,8 @@ QAlertDispatcher::~QAlertDispatcher() {
// with invalid tag it simply discard an alert. // with invalid tag it simply discard an alert.
{ {
QMutexLocker lock(&alerts_mutex); QMutexLocker lock(&current_tag->alerts_mutex);
*current_tag = 0; current_tag->dispatcher = 0;
current_tag.clear(); current_tag.clear();
} }
@ -60,45 +74,35 @@ QAlertDispatcher::~QAlertDispatcher() {
m_session->set_alert_dispatch(dispatch_function_t()); m_session->set_alert_dispatch(dispatch_function_t());
} }
void QAlertDispatcher::getPendingAlertsNoWait(std::deque<libtorrent::alert*>& out) { void QAlertDispatcher::getPendingAlertsNoWait(std::vector<libtorrent::alert*>& out) {
Q_ASSERT(out.empty()); Q_ASSERT(out.empty());
out.reserve(DEFAULT_ALERTS_CAPACITY);
QMutexLocker lock(&alerts_mutex); QMutexLocker lock(&current_tag->alerts_mutex);
alerts.swap(out); alerts.swap(out);
event_posted = false; event_posted = false;
} }
void QAlertDispatcher::getPendingAlerts(std::deque<libtorrent::alert*>& out, unsigned long time) { void QAlertDispatcher::getPendingAlerts(std::vector<libtorrent::alert*>& out, unsigned long time) {
Q_ASSERT(out.empty()); Q_ASSERT(out.empty());
out.reserve(DEFAULT_ALERTS_CAPACITY);
QMutexLocker lock(&alerts_mutex); QMutexLocker lock(&current_tag->alerts_mutex);
while (alerts.empty()) while (alerts.empty())
alerts_condvar.wait(&alerts_mutex, time); alerts_condvar.wait(&current_tag->alerts_mutex, time);
alerts.swap(out); alerts.swap(out);
event_posted = false; event_posted = false;
} }
void QAlertDispatcher::dispatch(QSharedPointer<QAtomicPointer<QAlertDispatcher> > tag, void QAlertDispatcher::dispatch(QSharedPointer<Tag> tag,
std::auto_ptr<libtorrent::alert> alert_ptr) { std::auto_ptr<libtorrent::alert> alert_ptr) {
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) QMutexLocker lock(&(tag->alerts_mutex));
QAlertDispatcher* that = tag->loadAcquire(); QAlertDispatcher* that = tag->dispatcher;
#else
QAlertDispatcher* that = *tag;
#endif
if (!that) if (!that)
return; return;
QMutexLocker lock(&(that->alerts_mutex));
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
if (!tag->load())
#else
if (!*tag)
#endif
return;
bool was_empty = that->alerts.empty(); bool was_empty = that->alerts.empty();
that->alerts.push_back(alert_ptr.get()); that->alerts.push_back(alert_ptr.get());
@ -122,7 +126,7 @@ void QAlertDispatcher::enqueueToMainThread() {
void QAlertDispatcher::deliverSignal() { void QAlertDispatcher::deliverSignal() {
emit alertsReceived(); emit alertsReceived();
QMutexLocker lock(&alerts_mutex); QMutexLocker lock(&current_tag->alerts_mutex);
event_posted = false; event_posted = false;
if (!alerts.empty()) if (!alerts.empty())

13
src/qtlibtorrent/alertdispatcher.h

@ -42,18 +42,20 @@ class QAlertDispatcher : public QObject {
Q_OBJECT Q_OBJECT
Q_DISABLE_COPY(QAlertDispatcher) Q_DISABLE_COPY(QAlertDispatcher)
struct Tag;
public: public:
QAlertDispatcher(libtorrent::session *session, QObject* parent); QAlertDispatcher(libtorrent::session *session, QObject* parent);
~QAlertDispatcher(); ~QAlertDispatcher();
void getPendingAlertsNoWait(std::deque<libtorrent::alert*>&); void getPendingAlertsNoWait(std::vector<libtorrent::alert*>&);
void getPendingAlerts(std::deque<libtorrent::alert*>&, unsigned long time = ULONG_MAX); void getPendingAlerts(std::vector<libtorrent::alert*>&, unsigned long time = ULONG_MAX);
signals: signals:
void alertsReceived(); void alertsReceived();
private: private:
static void dispatch(QSharedPointer<QAtomicPointer<QAlertDispatcher> >, static void dispatch(QSharedPointer<Tag>,
std::auto_ptr<libtorrent::alert>); std::auto_ptr<libtorrent::alert>);
void enqueueToMainThread(); void enqueueToMainThread();
@ -62,10 +64,9 @@ private slots:
private: private:
libtorrent::session *m_session; libtorrent::session *m_session;
QMutex alerts_mutex;
QWaitCondition alerts_condvar; QWaitCondition alerts_condvar;
std::deque<libtorrent::alert*> alerts; std::vector<libtorrent::alert*> alerts;
QSharedPointer<QAtomicPointer<QAlertDispatcher> > current_tag; QSharedPointer<Tag> current_tag;
bool event_posted; bool event_posted;
}; };

6
src/qtlibtorrent/qbtsession.cpp

@ -1649,7 +1649,7 @@ void QBtSession::saveFastResumeData() {
} catch(libtorrent::invalid_handle&) {} } catch(libtorrent::invalid_handle&) {}
} }
while (num_resume_data > 0) { while (num_resume_data > 0) {
std::deque<alert*> alerts; std::vector<alert*> alerts;
m_alertDispatcher->getPendingAlerts(alerts, 30*1000); m_alertDispatcher->getPendingAlerts(alerts, 30*1000);
if (alerts.empty()) { if (alerts.empty()) {
std::cerr << " aborting with " << num_resume_data << " outstanding " std::cerr << " aborting with " << num_resume_data << " outstanding "
@ -1657,7 +1657,7 @@ void QBtSession::saveFastResumeData() {
break; break;
} }
for (std::deque<alert*>::const_iterator i = alerts.begin(), end = alerts.end(); i != end; ++i) for (std::vector<alert*>::const_iterator i = alerts.begin(), end = alerts.end(); i != end; ++i)
{ {
alert const* a = *i; alert const* a = *i;
// Saving fastresume data can fail // Saving fastresume data can fail
@ -2147,7 +2147,7 @@ void QBtSession::sendNotificationEmail(const QTorrentHandle &h) {
// Read alerts sent by the Bittorrent session // Read alerts sent by the Bittorrent session
void QBtSession::readAlerts() { void QBtSession::readAlerts() {
typedef std::deque<alert*> alerts_t; typedef std::vector<alert*> alerts_t;
alerts_t alerts; alerts_t alerts;
m_alertDispatcher->getPendingAlertsNoWait(alerts); m_alertDispatcher->getPendingAlertsNoWait(alerts);

2
src/qtlibtorrent/torrentmodel.cpp

@ -549,7 +549,7 @@ void TorrentModel::stateUpdated(const std::vector<libtorrent::torrent_status> &s
for (statuses_t::const_iterator i = statuses.begin(), end = statuses.end(); i != end; ++i) { for (statuses_t::const_iterator i = statuses.begin(), end = statuses.end(); i != end; ++i) {
libtorrent::torrent_status const& status = *i; libtorrent::torrent_status const& status = *i;
const int row = torrentRow(misc::toQString(status.handle.info_hash())); const int row = torrentRow(misc::toQString(status.info_hash));
if (row >= 0) if (row >= 0)
m_torrents[row]->refreshStatus(status); m_torrents[row]->refreshStatus(status);
} }

Loading…
Cancel
Save