diff --git a/src/core/network.cpp b/src/core/network.cpp index 4194c4589..c30adb702 100644 --- a/src/core/network.cpp +++ b/src/core/network.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include "utilities.h" @@ -99,3 +100,31 @@ QNetworkReply* NetworkAccessManager::createRequest( return QNetworkAccessManager::createRequest(op, new_request, outgoingData); } + + +NetworkTimeouts::NetworkTimeouts(int timeout_msec, QObject* parent) + : timeout_msec_(timeout_msec) { +} + +void NetworkTimeouts::AddReply(QNetworkReply* reply) { + if (timers_.contains(reply)) + return; + + connect(reply, SIGNAL(destroyed()), SLOT(ReplyFinished())); + connect(reply, SIGNAL(finished()), SLOT(ReplyFinished())); + timers_[reply] = startTimer(timeout_msec_); +} + +void NetworkTimeouts::ReplyFinished() { + QNetworkReply* reply = reinterpret_cast(sender()); + if (timers_.contains(reply)) { + killTimer(timers_.take(reply)); + } +} + +void NetworkTimeouts::timerEvent(QTimerEvent* e) { + QNetworkReply* reply = timers_.key(e->timerId()); + if (reply) { + reply->abort(); + } +} diff --git a/src/core/network.h b/src/core/network.h index 7d5e85dd1..97d506887 100644 --- a/src/core/network.h +++ b/src/core/network.h @@ -54,4 +54,24 @@ protected: QIODevice* outgoingData); }; +class NetworkTimeouts : public QObject { + Q_OBJECT + +public: + NetworkTimeouts(int timeout_msec, QObject* parent = 0); + + void AddReply(QNetworkReply* reply); + void SetTimeout(int msec) { timeout_msec_ = msec; } + +protected: + void timerEvent(QTimerEvent* e); + +private slots: + void ReplyFinished(); + +private: + int timeout_msec_; + QMap timers_; +}; + #endif // NETWORK_H diff --git a/src/musicbrainz/musicbrainzclient.cpp b/src/musicbrainz/musicbrainzclient.cpp index 5df8676c2..b5c982840 100644 --- a/src/musicbrainz/musicbrainzclient.cpp +++ b/src/musicbrainz/musicbrainzclient.cpp @@ -24,10 +24,12 @@ #include const char* MusicBrainzClient::kUrl = "http://musicbrainz.org/ws/1/track/"; +const int MusicBrainzClient::kDefaultTimeout = 5000; // msec MusicBrainzClient::MusicBrainzClient(QObject* parent) : QObject(parent), - network_(new NetworkAccessManager(this)) + network_(new NetworkAccessManager(this)), + timeouts_(new NetworkTimeouts(kDefaultTimeout, this)) { } @@ -45,6 +47,8 @@ void MusicBrainzClient::Start(int id, const QString& puid) { QNetworkReply* reply = network_->get(req); connect(reply, SIGNAL(finished()), SLOT(RequestFinished())); requests_[reply] = id; + + timeouts_->AddReply(reply); } void MusicBrainzClient::Cancel(int id) { diff --git a/src/musicbrainz/musicbrainzclient.h b/src/musicbrainz/musicbrainzclient.h index f2169f8a8..f772af1ce 100644 --- a/src/musicbrainz/musicbrainzclient.h +++ b/src/musicbrainz/musicbrainzclient.h @@ -22,6 +22,8 @@ #include #include +class NetworkTimeouts; + class QNetworkAccessManager; class QNetworkReply; @@ -73,8 +75,10 @@ private: private: static const char* kUrl; + static const int kDefaultTimeout; QNetworkAccessManager* network_; + NetworkTimeouts* timeouts_; QMap requests_; }; diff --git a/src/musicbrainz/musicdnsclient.cpp b/src/musicbrainz/musicdnsclient.cpp index 18c3d4bb9..bd777d86e 100644 --- a/src/musicbrainz/musicdnsclient.cpp +++ b/src/musicbrainz/musicdnsclient.cpp @@ -25,13 +25,19 @@ const char* MusicDnsClient::kClientId = "c44f70e49000dd7c0d1388bff2bf4152"; const char* MusicDnsClient::kUrl = "http://ofa.musicdns.org/ofa/1/track"; +const int MusicDnsClient::kDefaultTimeout = 5000; // msec MusicDnsClient::MusicDnsClient(QObject* parent) : QObject(parent), - network_(new NetworkAccessManager(this)) + network_(new NetworkAccessManager(this)), + timeouts_(new NetworkTimeouts(kDefaultTimeout, this)) { } +void MusicDnsClient::SetTimeout(int msec) { + timeouts_->SetTimeout(msec); +} + void MusicDnsClient::Start(int id, const QString& fingerprint, int duration_msec) { typedef QPair Param; @@ -58,6 +64,8 @@ void MusicDnsClient::Start(int id, const QString& fingerprint, int duration_msec QNetworkReply* reply = network_->get(req); connect(reply, SIGNAL(finished()), SLOT(RequestFinished())); requests_[reply] = id; + + timeouts_->AddReply(reply); } void MusicDnsClient::Cancel(int id) { diff --git a/src/musicbrainz/musicdnsclient.h b/src/musicbrainz/musicdnsclient.h index 3e624173a..0e79280b6 100644 --- a/src/musicbrainz/musicdnsclient.h +++ b/src/musicbrainz/musicdnsclient.h @@ -21,6 +21,8 @@ #include #include +class NetworkTimeouts; + class QNetworkAccessManager; class QNetworkReply; @@ -38,6 +40,9 @@ class MusicDnsClient : public QObject { public: MusicDnsClient(QObject* parent = 0); + // Network requests will be aborted after this interval. + void SetTimeout(int msec); + // Starts a request and returns immediately. Finished() will be emitted // later with the same ID. void Start(int id, const QString& fingerprint, int duration_msec); @@ -59,8 +64,10 @@ private slots: private: static const char* kClientId; static const char* kUrl; + static const int kDefaultTimeout; QNetworkAccessManager* network_; + NetworkTimeouts* timeouts_; QMap requests_; };