diff --git a/src/qtlibtorrent/alertdispatcher.cpp b/src/qtlibtorrent/alertdispatcher.cpp index b9d3a7a53..ccfd3308c 100644 --- a/src/qtlibtorrent/alertdispatcher.cpp +++ b/src/qtlibtorrent/alertdispatcher.cpp @@ -33,12 +33,26 @@ #include #include +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) : QObject(parent) , m_session(session) - , current_tag(new QAtomicPointer(this)) + , current_tag(new Tag(this)) , event_posted(false) { + alerts.reserve(DEFAULT_ALERTS_CAPACITY); 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. { - QMutexLocker lock(&alerts_mutex); - *current_tag = 0; + QMutexLocker lock(¤t_tag->alerts_mutex); + current_tag->dispatcher = 0; current_tag.clear(); } @@ -60,45 +74,35 @@ QAlertDispatcher::~QAlertDispatcher() { m_session->set_alert_dispatch(dispatch_function_t()); } -void QAlertDispatcher::getPendingAlertsNoWait(std::deque& out) { +void QAlertDispatcher::getPendingAlertsNoWait(std::vector& out) { Q_ASSERT(out.empty()); + out.reserve(DEFAULT_ALERTS_CAPACITY); - QMutexLocker lock(&alerts_mutex); + QMutexLocker lock(¤t_tag->alerts_mutex); alerts.swap(out); event_posted = false; } -void QAlertDispatcher::getPendingAlerts(std::deque& out, unsigned long time) { +void QAlertDispatcher::getPendingAlerts(std::vector& out, unsigned long time) { Q_ASSERT(out.empty()); + out.reserve(DEFAULT_ALERTS_CAPACITY); - QMutexLocker lock(&alerts_mutex); + QMutexLocker lock(¤t_tag->alerts_mutex); while (alerts.empty()) - alerts_condvar.wait(&alerts_mutex, time); + alerts_condvar.wait(¤t_tag->alerts_mutex, time); alerts.swap(out); event_posted = false; } -void QAlertDispatcher::dispatch(QSharedPointer > tag, +void QAlertDispatcher::dispatch(QSharedPointer tag, std::auto_ptr alert_ptr) { -#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) - QAlertDispatcher* that = tag->loadAcquire(); -#else - QAlertDispatcher* that = *tag; -#endif + QMutexLocker lock(&(tag->alerts_mutex)); + QAlertDispatcher* that = tag->dispatcher; if (!that) 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(); that->alerts.push_back(alert_ptr.get()); @@ -122,7 +126,7 @@ void QAlertDispatcher::enqueueToMainThread() { void QAlertDispatcher::deliverSignal() { emit alertsReceived(); - QMutexLocker lock(&alerts_mutex); + QMutexLocker lock(¤t_tag->alerts_mutex); event_posted = false; if (!alerts.empty()) diff --git a/src/qtlibtorrent/alertdispatcher.h b/src/qtlibtorrent/alertdispatcher.h index a107bf4e1..aa2a9ec1f 100644 --- a/src/qtlibtorrent/alertdispatcher.h +++ b/src/qtlibtorrent/alertdispatcher.h @@ -42,18 +42,20 @@ class QAlertDispatcher : public QObject { Q_OBJECT Q_DISABLE_COPY(QAlertDispatcher) + struct Tag; + public: QAlertDispatcher(libtorrent::session *session, QObject* parent); ~QAlertDispatcher(); - void getPendingAlertsNoWait(std::deque&); - void getPendingAlerts(std::deque&, unsigned long time = ULONG_MAX); + void getPendingAlertsNoWait(std::vector&); + void getPendingAlerts(std::vector&, unsigned long time = ULONG_MAX); signals: void alertsReceived(); private: - static void dispatch(QSharedPointer >, + static void dispatch(QSharedPointer, std::auto_ptr); void enqueueToMainThread(); @@ -62,10 +64,9 @@ private slots: private: libtorrent::session *m_session; - QMutex alerts_mutex; QWaitCondition alerts_condvar; - std::deque alerts; - QSharedPointer > current_tag; + std::vector alerts; + QSharedPointer current_tag; bool event_posted; }; diff --git a/src/qtlibtorrent/qbtsession.cpp b/src/qtlibtorrent/qbtsession.cpp index 818cff613..f8378fc5a 100755 --- a/src/qtlibtorrent/qbtsession.cpp +++ b/src/qtlibtorrent/qbtsession.cpp @@ -1649,7 +1649,7 @@ void QBtSession::saveFastResumeData() { } catch(libtorrent::invalid_handle&) {} } while (num_resume_data > 0) { - std::deque alerts; + std::vector alerts; m_alertDispatcher->getPendingAlerts(alerts, 30*1000); if (alerts.empty()) { std::cerr << " aborting with " << num_resume_data << " outstanding " @@ -1657,7 +1657,7 @@ void QBtSession::saveFastResumeData() { break; } - for (std::deque::const_iterator i = alerts.begin(), end = alerts.end(); i != end; ++i) + for (std::vector::const_iterator i = alerts.begin(), end = alerts.end(); i != end; ++i) { alert const* a = *i; // Saving fastresume data can fail @@ -2147,7 +2147,7 @@ void QBtSession::sendNotificationEmail(const QTorrentHandle &h) { // Read alerts sent by the Bittorrent session void QBtSession::readAlerts() { - typedef std::deque alerts_t; + typedef std::vector alerts_t; alerts_t alerts; m_alertDispatcher->getPendingAlertsNoWait(alerts); diff --git a/src/qtlibtorrent/torrentmodel.cpp b/src/qtlibtorrent/torrentmodel.cpp index 3dca808c7..419361ec1 100644 --- a/src/qtlibtorrent/torrentmodel.cpp +++ b/src/qtlibtorrent/torrentmodel.cpp @@ -549,7 +549,7 @@ void TorrentModel::stateUpdated(const std::vector &s for (statuses_t::const_iterator i = statuses.begin(), end = statuses.end(); i != end; ++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) m_torrents[row]->refreshStatus(status); }