Provide instance()-method for Utils::NetworkAccessManager.

Preemptively fix exit warning "QEventLoop cannot be used
without QApplication" (Qt 5/dev) emitted by destruction of
the of the generic highlighter manager singleton which had a
member of type Utils::NetworkAccessManager.

Use a single instance of Utils::NetworkAccessManager for the
main thread and clean up properly using a qAddPostRoutine().

Change-Id: Ida57b9028a79eb4927818ce49088ea567f3bdfd6
Reviewed-by: hjk <hjk121@nokiamail.com>
Reviewed-by: Peter Hartmann <phartmann@blackberry.com>
Reviewed-by: Eike Ziller <eike.ziller@digia.com>
This commit is contained in:
Friedemann Kleint
2013-04-09 09:58:17 +02:00
parent 2ead48fb26
commit 9d7e786b03
21 changed files with 54 additions and 103 deletions

View File

@@ -43,10 +43,30 @@
\brief Network Access Manager for use with Qt Creator. \brief Network Access Manager for use with Qt Creator.
Common initialization, Qt Creator User Agent Common initialization, Qt Creator User Agent
Preferably, the instance returned by NetworkAccessManager::instance() should be used for the main
thread. The constructor is provided only for multithreaded use.
*/ */
namespace Utils { namespace Utils {
static NetworkAccessManager *namInstance = 0;
void cleanupNetworkAccessManager()
{
delete namInstance;
namInstance = 0;
}
NetworkAccessManager *NetworkAccessManager::instance()
{
if (!namInstance) {
namInstance = new NetworkAccessManager;
qAddPostRoutine(cleanupNetworkAccessManager);
}
return namInstance;
}
static const QString getOsString() static const QString getOsString()
{ {
QString osString; QString osString;

View File

@@ -44,6 +44,8 @@ class QTCREATOR_UTILS_EXPORT NetworkAccessManager : public QNetworkAccessManager
public: public:
NetworkAccessManager(QObject *parent = 0); NetworkAccessManager(QObject *parent = 0);
static NetworkAccessManager *instance();
public slots: public slots:
void getUrl(const QUrl &url); void getUrl(const QUrl &url);

View File

@@ -43,8 +43,7 @@ enum { debug = 0 };
namespace CodePaster { namespace CodePaster {
CodePasterProtocol::CodePasterProtocol(const NetworkAccessManagerProxyPtr &nw) : CodePasterProtocol::CodePasterProtocol() :
NetworkProtocol(nw),
m_page(new CodePaster::CodePasterSettingsPage), m_page(new CodePaster::CodePasterSettingsPage),
m_pasteReply(0), m_pasteReply(0),
m_fetchReply(0), m_fetchReply(0),

View File

@@ -44,7 +44,7 @@ class CodePasterProtocol : public NetworkProtocol
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit CodePasterProtocol(const NetworkAccessManagerProxyPtr &nw); explicit CodePasterProtocol();
~CodePasterProtocol(); ~CodePasterProtocol();
QString name() const; QString name() const;

View File

@@ -130,11 +130,10 @@ bool CodepasterPlugin::initialize(const QStringList &arguments, QString *errorMe
addAutoReleasedObject(settingsPage); addAutoReleasedObject(settingsPage);
// Create the protocols and append them to the Settings // Create the protocols and append them to the Settings
const QSharedPointer<NetworkAccessManagerProxy> networkAccessMgrProxy(new NetworkAccessManagerProxy); Protocol *protos[] = { new PasteBinDotComProtocol,
Protocol *protos[] = { new PasteBinDotComProtocol(networkAccessMgrProxy), new PasteBinDotCaProtocol,
new PasteBinDotCaProtocol(networkAccessMgrProxy), new KdePasteProtocol,
new KdePasteProtocol(networkAccessMgrProxy), new CodePasterProtocol,
new CodePasterProtocol(networkAccessMgrProxy),
new FileShareProtocol new FileShareProtocol
}; };
const int count = sizeof(protos) / sizeof(Protocol *); const int count = sizeof(protos) / sizeof(Protocol *);
@@ -148,7 +147,7 @@ bool CodepasterPlugin::initialize(const QStringList &arguments, QString *errorMe
m_protocols.append(protos[i]); m_protocols.append(protos[i]);
} }
m_urlOpen = new UrlOpenProtocol(networkAccessMgrProxy); m_urlOpen = new UrlOpenProtocol;
connect(m_urlOpen, SIGNAL(fetchDone(QString,QString,bool)), connect(m_urlOpen, SIGNAL(fetchDone(QString,QString,bool)),
this, SLOT(finishFetch(QString,QString,bool))); this, SLOT(finishFetch(QString,QString,bool)));

View File

@@ -49,13 +49,12 @@ class PasteReceiver : public QObject
public: public:
PasteReceiver(const QString &protocol, const QString &filePath) : m_filePath(filePath) PasteReceiver(const QString &protocol, const QString &filePath) : m_filePath(filePath)
{ {
const QSharedPointer<NetworkAccessManagerProxy> accessMgr(new NetworkAccessManagerProxy);
if (protocol == KdePasteProtocol::protocolName().toLower()) if (protocol == KdePasteProtocol::protocolName().toLower())
m_protocol.reset(new KdePasteProtocol(accessMgr)); m_protocol.reset(new KdePasteProtocol);
else if (protocol == PasteBinDotCaProtocol::protocolName().toLower()) else if (protocol == PasteBinDotCaProtocol::protocolName().toLower())
m_protocol.reset(new PasteBinDotCaProtocol(accessMgr)); m_protocol.reset(new PasteBinDotCaProtocol);
else if (protocol == PasteBinDotComProtocol::protocolName().toLower()) else if (protocol == PasteBinDotComProtocol::protocolName().toLower())
m_protocol.reset(new PasteBinDotComProtocol(accessMgr)); m_protocol.reset(new PasteBinDotComProtocol);
else else
qFatal("Internal error: Invalid protocol."); qFatal("Internal error: Invalid protocol.");
} }

View File

@@ -44,8 +44,7 @@ static const char hostUrlC[]= "http://paste.kde.org/";
static const char showPhpScriptpC[] = "show.php"; static const char showPhpScriptpC[] = "show.php";
namespace CodePaster { namespace CodePaster {
KdePasteProtocol::KdePasteProtocol(const NetworkAccessManagerProxyPtr &nw) : KdePasteProtocol::KdePasteProtocol() :
NetworkProtocol(nw),
m_fetchReply(0), m_fetchReply(0),
m_pasteReply(0), m_pasteReply(0),
m_listReply(0), m_listReply(0),

View File

@@ -38,7 +38,7 @@ class KdePasteProtocol : public NetworkProtocol
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit KdePasteProtocol(const NetworkAccessManagerProxyPtr &nw); KdePasteProtocol();
static QString protocolName(); static QString protocolName();
QString name() const { return protocolName(); } QString name() const { return protocolName(); }

View File

@@ -39,8 +39,7 @@
static const char urlC[] = "http://pastebin.ca/"; static const char urlC[] = "http://pastebin.ca/";
namespace CodePaster { namespace CodePaster {
PasteBinDotCaProtocol::PasteBinDotCaProtocol(const NetworkAccessManagerProxyPtr &nw) : PasteBinDotCaProtocol::PasteBinDotCaProtocol() :
NetworkProtocol(nw),
m_fetchReply(0), m_fetchReply(0),
m_listReply(0), m_listReply(0),
m_pasteReply(0), m_pasteReply(0),

View File

@@ -37,7 +37,7 @@ class PasteBinDotCaProtocol : public NetworkProtocol
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit PasteBinDotCaProtocol(const NetworkAccessManagerProxyPtr &nw); explicit PasteBinDotCaProtocol();
static QString protocolName() { return QLatin1String("Pastebin.Ca"); } static QString protocolName() { return QLatin1String("Pastebin.Ca"); }
QString name() const { return protocolName(); } QString name() const { return protocolName(); }

View File

@@ -49,8 +49,7 @@ static const char PASTEBIN_ARCHIVE[]="archive";
static const char API_KEY[]="api_dev_key=516686fc461fb7f9341fd7cf2af6f829&"; // user: qtcreator_apikey static const char API_KEY[]="api_dev_key=516686fc461fb7f9341fd7cf2af6f829&"; // user: qtcreator_apikey
namespace CodePaster { namespace CodePaster {
PasteBinDotComProtocol::PasteBinDotComProtocol(const NetworkAccessManagerProxyPtr &nw) : PasteBinDotComProtocol::PasteBinDotComProtocol() :
NetworkProtocol(nw),
m_fetchReply(0), m_fetchReply(0),
m_pasteReply(0), m_pasteReply(0),
m_listReply(0), m_listReply(0),

View File

@@ -38,7 +38,7 @@ class PasteBinDotComProtocol : public NetworkProtocol
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit PasteBinDotComProtocol(const NetworkAccessManagerProxyPtr &nw); PasteBinDotComProtocol();
static QString protocolName(); static QString protocolName();
QString name() const { return protocolName(); } QString name() const { return protocolName(); }

View File

@@ -175,45 +175,23 @@ bool Protocol::showConfigurationError(const Protocol *p,
return rc; return rc;
} }
// --------- NetworkProtocol
// ------------ NetworkAccessManagerProxy QNetworkReply *NetworkProtocol::httpGet(const QString &link)
NetworkAccessManagerProxy::NetworkAccessManagerProxy()
{
}
NetworkAccessManagerProxy::~NetworkAccessManagerProxy()
{
}
QNetworkReply *NetworkAccessManagerProxy::httpGet(const QString &link)
{ {
QUrl url(link); QUrl url(link);
QNetworkRequest r(url); QNetworkRequest r(url);
return networkAccessManager()->get(r); return Utils::NetworkAccessManager::instance()->get(r);
} }
QNetworkReply *NetworkAccessManagerProxy::httpPost(const QString &link, const QByteArray &data) QNetworkReply *NetworkProtocol::httpPost(const QString &link, const QByteArray &data)
{ {
QUrl url(link); QUrl url(link);
QNetworkRequest r(url); QNetworkRequest r(url);
// Required for Qt 4.8 // Required for Qt 4.8
r.setHeader(QNetworkRequest::ContentTypeHeader, r.setHeader(QNetworkRequest::ContentTypeHeader,
QVariant(QByteArray("application/x-www-form-urlencoded"))); QVariant(QByteArray("application/x-www-form-urlencoded")));
return networkAccessManager()->post(r, data); return Utils::NetworkAccessManager::instance()->post(r, data);
}
QNetworkAccessManager *NetworkAccessManagerProxy::networkAccessManager()
{
if (m_networkAccessManager.isNull())
m_networkAccessManager.reset(new Utils::NetworkAccessManager);
return m_networkAccessManager.data();
}
// --------- NetworkProtocol
NetworkProtocol::NetworkProtocol(const NetworkAccessManagerProxyPtr &nw) :
m_networkAccessManager(nw)
{
} }
NetworkProtocol::~NetworkProtocol() NetworkProtocol::~NetworkProtocol()

View File

@@ -105,26 +105,6 @@ protected:
static QString fixNewLines(QString in); static QString fixNewLines(QString in);
}; };
/* Proxy for NetworkAccessManager that can be shared with
* delayed initialization and conveniences
* for HTTP-requests. */
class NetworkAccessManagerProxy
{
Q_DISABLE_COPY(NetworkAccessManagerProxy)
public:
NetworkAccessManagerProxy();
~NetworkAccessManagerProxy();
QNetworkReply *httpGet(const QString &url);
QNetworkReply *httpPost(const QString &link, const QByteArray &data);
QNetworkAccessManager *networkAccessManager();
private:
QScopedPointer<QNetworkAccessManager> m_networkAccessManager;
};
/* Network-based protocol: Provides access with delayed /* Network-based protocol: Provides access with delayed
* initialization to a QNetworkAccessManager and conveniences * initialization to a QNetworkAccessManager and conveniences
* for HTTP-requests. */ * for HTTP-requests. */
@@ -137,24 +117,12 @@ public:
virtual ~NetworkProtocol(); virtual ~NetworkProtocol();
protected: protected:
typedef QSharedPointer<NetworkAccessManagerProxy> NetworkAccessManagerProxyPtr; QNetworkReply *httpGet(const QString &url);
explicit NetworkProtocol(const NetworkAccessManagerProxyPtr &nw); QNetworkReply *httpPost(const QString &link, const QByteArray &data);
inline QNetworkReply *httpGet(const QString &url)
{ return m_networkAccessManager->httpGet(url); }
inline QNetworkReply *httpPost(const QString &link, const QByteArray &data)
{ return m_networkAccessManager->httpPost(link, data); }
inline QNetworkAccessManager *networkAccessManager()
{ return m_networkAccessManager->networkAccessManager(); }
// Check connectivity of host, displaying a message box. // Check connectivity of host, displaying a message box.
bool httpStatus(QString url, QString *errorMessage); bool httpStatus(QString url, QString *errorMessage);
private:
const NetworkAccessManagerProxyPtr m_networkAccessManager;
}; };
} //namespace CodePaster } //namespace CodePaster

View File

@@ -35,8 +35,8 @@
using namespace CodePaster; using namespace CodePaster;
UrlOpenProtocol::UrlOpenProtocol(const NetworkAccessManagerProxyPtr &nw) UrlOpenProtocol::UrlOpenProtocol()
: NetworkProtocol(nw), m_fetchReply(0) : m_fetchReply(0)
{ {
} }

View File

@@ -38,7 +38,7 @@ class UrlOpenProtocol : public NetworkProtocol
{ {
Q_OBJECT Q_OBJECT
public: public:
UrlOpenProtocol(const NetworkAccessManagerProxyPtr &nw); UrlOpenProtocol();
QString name() const; QString name() const;
unsigned capabilities() const; unsigned capabilities() const;

View File

@@ -357,11 +357,6 @@ void GitoriousProjectReader::readUnknownElement(QXmlStreamReader &reader)
// --- Gitorious // --- Gitorious
Gitorious::Gitorious() :
m_networkManager(0)
{
}
Gitorious &Gitorious::instance() Gitorious &Gitorious::instance()
{ {
static Gitorious gitorious; static Gitorious gitorious;
@@ -523,9 +518,7 @@ void Gitorious::slotReplyFinished()
// dispatch. Use host name in case an entry is removed in-between // dispatch. Use host name in case an entry is removed in-between
QNetworkReply *Gitorious::createRequest(const QUrl &url, int protocol, int hostIndex, int page) QNetworkReply *Gitorious::createRequest(const QUrl &url, int protocol, int hostIndex, int page)
{ {
if (!m_networkManager) QNetworkReply *reply = Utils::NetworkAccessManager::instance()->get(QNetworkRequest(url));
m_networkManager = new Utils::NetworkAccessManager(this);
QNetworkReply *reply = m_networkManager->get(QNetworkRequest(url));
connect(reply, SIGNAL(finished()), this, SLOT(slotReplyFinished())); connect(reply, SIGNAL(finished()), this, SLOT(slotReplyFinished()));
reply->setProperty(protocolPropertyC, QVariant(protocol)); reply->setProperty(protocolPropertyC, QVariant(protocol));
reply->setProperty(hostNamePropertyC, QVariant(hostName(hostIndex))); reply->setProperty(hostNamePropertyC, QVariant(hostName(hostIndex)));

View File

@@ -36,7 +36,6 @@
#include <QObject> #include <QObject>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QNetworkAccessManager;
class QNetworkReply; class QNetworkReply;
class QDebug; class QDebug;
class QUrl; class QUrl;
@@ -159,7 +158,7 @@ private slots:
void slotReplyFinished(); void slotReplyFinished();
private: private:
Gitorious(); Gitorious() {}
void listProjectsReply(int hostIndex, int page, const QByteArray &data); void listProjectsReply(int hostIndex, int page, const QByteArray &data);
void listCategoriesReply(int index, QByteArray data); void listCategoriesReply(int index, QByteArray data);
void emitError(const QString &e); void emitError(const QString &e);
@@ -167,7 +166,6 @@ private:
void startProjectsRequest(int index, int page = 1); void startProjectsRequest(int index, int page = 1);
QList<GitoriousHost> m_hosts; QList<GitoriousHost> m_hosts;
QNetworkAccessManager *m_networkManager;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -48,12 +48,12 @@ DefinitionDownloader::DefinitionDownloader(const QUrl &url, const QString &local
void DefinitionDownloader::run() void DefinitionDownloader::run()
{ {
Utils::NetworkAccessManager manager; Utils::NetworkAccessManager *manager = Utils::NetworkAccessManager::instance();
int currentAttempt = 0; int currentAttempt = 0;
const int maxAttempts = 5; const int maxAttempts = 5;
while (currentAttempt < maxAttempts) { while (currentAttempt < maxAttempts) {
QScopedPointer<QNetworkReply> reply(getData(&manager)); QScopedPointer<QNetworkReply> reply(getData(manager));
if (reply->error() != QNetworkReply::NoError) { if (reply->error() != QNetworkReply::NoError) {
m_status = NetworkError; m_status = NetworkError;
return; return;

View File

@@ -41,6 +41,7 @@
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/progressmanager/progressmanager.h> #include <coreplugin/progressmanager/progressmanager.h>
#include <utils/QtConcurrentTools> #include <utils/QtConcurrentTools>
#include <utils/networkaccessmanager.h>
#include <QtAlgorithms> #include <QtAlgorithms>
#include <QString> #include <QString>
@@ -423,7 +424,7 @@ void Manager::downloadAvailableDefinitionsMetaData()
QUrl url(QLatin1String("http://www.kate-editor.org/syntax/update-3.9.xml")); QUrl url(QLatin1String("http://www.kate-editor.org/syntax/update-3.9.xml"));
QNetworkRequest request(url); QNetworkRequest request(url);
// Currently this takes a couple of seconds on Windows 7: QTBUG-10106. // Currently this takes a couple of seconds on Windows 7: QTBUG-10106.
QNetworkReply *reply = m_networkManager.get(request); QNetworkReply *reply = Utils::NetworkAccessManager::instance()->get(request);
connect(reply, SIGNAL(finished()), this, SLOT(downloadAvailableDefinitionsListFinished())); connect(reply, SIGNAL(finished()), this, SLOT(downloadAvailableDefinitionsListFinished()));
} }

View File

@@ -43,8 +43,6 @@
#include <QSharedPointer> #include <QSharedPointer>
#include <QFutureWatcher> #include <QFutureWatcher>
#include <utils/networkaccessmanager.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QFileInfo; class QFileInfo;
class QStringList; class QStringList;
@@ -101,7 +99,6 @@ private:
bool m_isDownloadingDefinitionsSpec; bool m_isDownloadingDefinitionsSpec;
QList<DefinitionDownloader *> m_downloaders; QList<DefinitionDownloader *> m_downloaders;
QFutureWatcher<void> m_downloadWatcher; QFutureWatcher<void> m_downloadWatcher;
Utils::NetworkAccessManager m_networkManager;
QList<HighlightDefinitionMetaData> parseAvailableDefinitionsList(QIODevice *device) const; QList<HighlightDefinitionMetaData> parseAvailableDefinitionsList(QIODevice *device) const;
QSet<QString> m_isBuildingDefinition; QSet<QString> m_isBuildingDefinition;