|
|
|
@ -33,12 +33,26 @@
@@ -33,12 +33,26 @@
|
|
|
|
|
#include <boost/bind.hpp> |
|
|
|
|
#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) |
|
|
|
|
: QObject(parent) |
|
|
|
|
, m_session(session) |
|
|
|
|
, current_tag(new QAtomicPointer<QAlertDispatcher>(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() {
@@ -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() {
@@ -60,45 +74,35 @@ QAlertDispatcher::~QAlertDispatcher() {
|
|
|
|
|
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()); |
|
|
|
|
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<libtorrent::alert*>& out, unsigned long time) { |
|
|
|
|
void QAlertDispatcher::getPendingAlerts(std::vector<libtorrent::alert*>& 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<QAtomicPointer<QAlertDispatcher> > tag, |
|
|
|
|
void QAlertDispatcher::dispatch(QSharedPointer<Tag> tag, |
|
|
|
|
std::auto_ptr<libtorrent::alert> 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() {
@@ -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()) |
|
|
|
|