diff --git a/src/libtomahawk/utils/tomahawkutils.cpp b/src/libtomahawk/utils/tomahawkutils.cpp
index affbdcc00..72d1867cd 100644
--- a/src/libtomahawk/utils/tomahawkutils.cpp
+++ b/src/libtomahawk/utils/tomahawkutils.cpp
@@ -16,6 +16,7 @@
* along with Tomahawk. If not, see .
*/
+#include "config.h"
#include "tomahawkutils.h"
#include "headlesscheck.h"
@@ -28,6 +29,7 @@
#include
#include
#include
+#include
#include
#include
@@ -60,6 +62,10 @@
#include "utils/logger.h"
#include "config.h"
+#ifdef LIBLASTFM_FOUND
+#include
+#endif
+
namespace TomahawkUtils
{
@@ -459,8 +465,11 @@ unmarginLayout( QLayout* layout )
}
-static QWeakPointer< QNetworkAccessManager > s_nam;
-static NetworkProxyFactory* s_proxyFactory = 0;
+NetworkProxyFactory::NetworkProxyFactory( const NetworkProxyFactory& other )
+{
+ m_noProxyHosts = QStringList( other.m_noProxyHosts );
+ m_proxy = QNetworkProxy( other.m_proxy );
+}
QList< QNetworkProxy >
@@ -491,13 +500,14 @@ void
NetworkProxyFactory::setNoProxyHosts( const QStringList& hosts )
{
QStringList newList;
+ qDebug() << Q_FUNC_INFO << "No-proxy hosts:" << hosts;
foreach( QString host, hosts )
{
QString munge = host.simplified();
newList << munge;
//TODO: wildcard support
}
- qDebug() << Q_FUNC_INFO << "No-proxy hosts:" << newList;
+ qDebug() << Q_FUNC_INFO << "New no-proxy hosts:" << newList;
m_noProxyHosts = newList;
}
@@ -515,20 +525,40 @@ NetworkProxyFactory::setProxy( const QNetworkProxy& proxy )
bool NetworkProxyFactory::operator==( const NetworkProxyFactory& other )
{
- if ( m_noProxyHosts != other.m_noProxyHosts or m_proxy != other.m_proxy )
+ if ( m_noProxyHosts != other.m_noProxyHosts || m_proxy != other.m_proxy )
return false;
return true;
}
+static QMap< QThread*, QNetworkAccessManager* > s_threadNamHash;
+static QMap< QThread*, NetworkProxyFactory* > s_threadProxyFactoryHash;
+static QMutex s_namAccessMutex;
NetworkProxyFactory*
-proxyFactory()
+proxyFactory( bool noMutexLocker )
{
- if ( !s_proxyFactory )
- s_proxyFactory = new NetworkProxyFactory();
+ // Don't lock if being called from nam()
+ QMutexLocker locker( noMutexLocker ? new QMutex() : &s_namAccessMutex );
+
+ if ( s_threadProxyFactoryHash.contains( QThread::currentThread() ) )
+ return s_threadProxyFactoryHash[ QThread::currentThread() ];
- return s_proxyFactory;
+ if ( !s_threadProxyFactoryHash.contains( TOMAHAWK_APPLICATION::instance()->thread() ) )
+ return 0;
+
+ // create a new proxy factory for this thread
+ TomahawkUtils::NetworkProxyFactory *mainProxyFactory = s_threadProxyFactoryHash[ TOMAHAWK_APPLICATION::instance()->thread() ];
+ TomahawkUtils::NetworkProxyFactory *newProxyFactory = new TomahawkUtils::NetworkProxyFactory();
+ newProxyFactory->setNoProxyHosts( mainProxyFactory->noProxyHosts() );
+ newProxyFactory->setProxy( QNetworkProxy ( mainProxyFactory->proxy() ) );
+
+ s_threadProxyFactoryHash[ QThread::currentThread() ] = newProxyFactory;
+
+ if ( s_threadNamHash.contains( QThread::currentThread() ) )
+ s_threadNamHash[ QThread::currentThread() ]->setProxyFactory( newProxyFactory );
+
+ return newProxyFactory;
}
@@ -536,27 +566,65 @@ void
setProxyFactory( NetworkProxyFactory* factory )
{
Q_ASSERT( factory );
- s_proxyFactory = factory;
- NetworkProxyFactory::setApplicationProxyFactory( s_proxyFactory );
- //nam takes ownership so set a copy, not the global one
- if ( !s_nam.isNull() )
+ QMutexLocker locker( &s_namAccessMutex );
+
+ if ( !s_threadProxyFactoryHash.contains( TOMAHAWK_APPLICATION::instance()->thread() ) )
+ return;
+
+ if ( QThread::currentThread() == TOMAHAWK_APPLICATION::instance()->thread() )
{
- TomahawkUtils::NetworkProxyFactory* newProxyFactory = new TomahawkUtils::NetworkProxyFactory();
- newProxyFactory->setNoProxyHosts( factory->noProxyHosts() );
- QNetworkProxy newProxy( factory->proxy() );
- newProxyFactory->setProxy( newProxy );
- s_nam.data()->setProxyFactory( newProxyFactory );
+ // If setting new values on the main thread, clear the other entries
+ // so that on next access new ones will be created with new proper values
+ NetworkProxyFactory::setApplicationProxyFactory( factory );
+ s_threadProxyFactoryHash.clear();
}
+
+ // Yes, we really do need to create a new one, or we will crash when we set the factory
+ // in the QNAM, because it deletes the old one -- and guess what happens when the old one is
+ // the same as the new one?
+ TomahawkUtils::NetworkProxyFactory *mainProxyFactory = factory;
+ TomahawkUtils::NetworkProxyFactory *newProxyFactory = new TomahawkUtils::NetworkProxyFactory();
+ newProxyFactory->setNoProxyHosts( mainProxyFactory->noProxyHosts() );
+ newProxyFactory->setProxy( QNetworkProxy ( mainProxyFactory->proxy() ) );
+
+ s_threadProxyFactoryHash[ QThread::currentThread() ] = newProxyFactory;
+
+ if ( s_threadNamHash.contains( QThread::currentThread() ) )
+ s_threadNamHash[ QThread::currentThread() ]->setProxyFactory( newProxyFactory );
}
QNetworkAccessManager*
nam()
{
- if ( s_nam.isNull() )
+ QMutexLocker locker( &s_namAccessMutex );
+ if ( s_threadNamHash.contains( QThread::currentThread() ) )
+ {
+ // Ensure the proxy values are up to date
+ Q_UNUSED( proxyFactory( true ) );
+ return s_threadNamHash[ QThread::currentThread() ];
+ }
+
+ if ( !s_threadNamHash.contains( TOMAHAWK_APPLICATION::instance()->thread() ) )
return 0;
- return s_nam.data();
+ // Create a nam for this thread based on the main thread's settings but with its own proxyfactory
+ QNetworkAccessManager *mainNam = s_threadNamHash[ TOMAHAWK_APPLICATION::instance()->thread() ];
+ QNetworkAccessManager* newNam;
+#ifdef LIBLASTFM_FOUND
+ newNam = lastfm::nam();
+#else
+ newNam = new QNetworkAccessManager();
+#endif
+
+ newNam->setConfiguration( QNetworkConfiguration( mainNam->configuration() ) );
+ newNam->setNetworkAccessible( mainNam->networkAccessible() );
+
+ s_threadNamHash[ QThread::currentThread() ] = newNam;
+ //get the proxy info, must be done *after* setting the new thread in the hash
+ Q_UNUSED( proxyFactory( true ) );
+
+ return newNam;
}
@@ -564,7 +632,39 @@ void
setNam( QNetworkAccessManager* nam )
{
Q_ASSERT( nam );
- s_nam = QWeakPointer< QNetworkAccessManager >( nam );
+ QMutexLocker locker( &s_namAccessMutex );
+ if ( !s_threadNamHash.contains( TOMAHAWK_APPLICATION::instance()->thread() ) &&
+ QThread::currentThread() == TOMAHAWK_APPLICATION::instance()->thread() )
+ {
+ // Should only get here on first initialization of the nam
+ TomahawkSettings *s = TomahawkSettings::instance();
+ TomahawkUtils::NetworkProxyFactory* proxyFactory = new TomahawkUtils::NetworkProxyFactory();
+ if ( s->proxyType() != QNetworkProxy::NoProxy && !s->proxyHost().isEmpty() )
+ {
+ tDebug( LOGEXTRA ) << "Setting proxy to saved values";
+ QNetworkProxy proxy( static_cast( s->proxyType() ), s->proxyHost(), s->proxyPort(), s->proxyUsername(), s->proxyPassword() );
+ proxyFactory->setProxy( proxy );
+ //TODO: On Windows and Mac because liblastfm sets an application level proxy it may override our factory, so may need to explicitly do
+ //a QNetworkProxy::setApplicationProxy with our own proxy (but then also overriding our own factory :-( )
+ }
+ if ( !s->proxyNoProxyHosts().isEmpty() )
+ proxyFactory->setNoProxyHosts( s->proxyNoProxyHosts().split( ',', QString::SkipEmptyParts ) );
+
+ nam->setProxyFactory( proxyFactory );
+ s_threadNamHash[ QThread::currentThread() ] = nam;
+ s_threadProxyFactoryHash[ QThread::currentThread() ] = proxyFactory;
+ NetworkProxyFactory::setApplicationProxyFactory( proxyFactory );
+ return;
+ }
+
+ if ( QThread::currentThread() == TOMAHAWK_APPLICATION::instance()->thread() )
+ {
+ // If setting new values on the main thread, clear the other entries
+ // so that on next access new ones will be created with new proper values
+ s_threadNamHash.clear();
+ s_threadProxyFactoryHash.clear();
+ }
+ s_threadNamHash[ QThread::currentThread() ] = nam;
}
diff --git a/src/libtomahawk/utils/tomahawkutils.h b/src/libtomahawk/utils/tomahawkutils.h
index 924045a1d..18526ed9b 100644
--- a/src/libtomahawk/utils/tomahawkutils.h
+++ b/src/libtomahawk/utils/tomahawkutils.h
@@ -55,6 +55,7 @@ namespace TomahawkUtils
: m_proxy( QNetworkProxy::NoProxy )
{}
+ NetworkProxyFactory( const NetworkProxyFactory &other );
virtual ~NetworkProxyFactory() {}
virtual QList< QNetworkProxy > queryProxy( const QNetworkProxyQuery & query = QNetworkProxyQuery() );
@@ -92,7 +93,7 @@ namespace TomahawkUtils
DLLEXPORT void unmarginLayout( QLayout* layout );
- DLLEXPORT NetworkProxyFactory* proxyFactory();
+ DLLEXPORT NetworkProxyFactory* proxyFactory( bool noMutexLocker = false );
DLLEXPORT QNetworkAccessManager* nam();
DLLEXPORT void setProxyFactory( TomahawkUtils::NetworkProxyFactory* factory );
diff --git a/src/proxydialog.ui b/src/proxydialog.ui
index 239957358..4b30ca1ca 100644
--- a/src/proxydialog.ui
+++ b/src/proxydialog.ui
@@ -146,7 +146,7 @@
-
- localhost, *.example.com
+ localhost *.example.com (space separated)
diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp
index 0c75b151c..4a19a46e1 100644
--- a/src/settingsdialog.cpp
+++ b/src/settingsdialog.cpp
@@ -892,9 +892,14 @@ ProxyDialog::saveSettings()
return;
TomahawkUtils::NetworkProxyFactory* proxyFactory = new TomahawkUtils::NetworkProxyFactory();
+ tDebug() << Q_FUNC_INFO << "Got proxyFactory: " << proxyFactory;
QNetworkProxy proxy( static_cast(s->proxyType()), s->proxyHost(), s->proxyPort(), s->proxyUsername(), s->proxyPassword() );
proxyFactory->setProxy( proxy );
if ( !ui->noHostLineEdit->text().isEmpty() )
- proxyFactory->setNoProxyHosts( ui->noHostLineEdit->text().split( ',', QString::SkipEmptyParts ) );
+ {
+ tDebug() << Q_FUNC_INFO << "hosts line edit is " << ui->noHostLineEdit->text();
+ tDebug() << Q_FUNC_INFO << "split hosts line edit is " << ui->noHostLineEdit->text().split( ' ', QString::SkipEmptyParts );
+ proxyFactory->setNoProxyHosts( ui->noHostLineEdit->text().split( ' ', QString::SkipEmptyParts ) );
+ }
TomahawkUtils::setProxyFactory( proxyFactory );
}
diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp
index 9d0fa6864..860a1c560 100644
--- a/src/tomahawkapp.cpp
+++ b/src/tomahawkapp.cpp
@@ -19,8 +19,6 @@
#include "tomahawkapp.h"
-#include "config.h"
-
#include
#include
@@ -170,21 +168,6 @@ TomahawkApp::init()
lastfm::setNetworkAccessManager( TomahawkUtils::nam() );
#endif
- TomahawkUtils::NetworkProxyFactory* proxyFactory = new TomahawkUtils::NetworkProxyFactory();
- if ( s->proxyType() != QNetworkProxy::NoProxy && !s->proxyHost().isEmpty() )
- {
- tDebug( LOGEXTRA ) << "Setting proxy to saved values";
- QNetworkProxy proxy( static_cast( s->proxyType() ), s->proxyHost(), s->proxyPort(), s->proxyUsername(), s->proxyPassword() );
- proxyFactory->setProxy( proxy );
- //TODO: On Windows and Mac because liblastfm sets an application level proxy it may override our factory, so may need to explicitly do
- //a QNetworkProxy::setApplicationProxy with our own proxy (but then also overriding our own factory :-( )
- }
- if ( !s->proxyNoProxyHosts().isEmpty() )
- proxyFactory->setNoProxyHosts( s->proxyNoProxyHosts().split( ',', QString::SkipEmptyParts ) );
-
- TomahawkUtils::setProxyFactory( proxyFactory );
-
-
m_audioEngine = QWeakPointer( new AudioEngine );
m_scanManager = QWeakPointer( new ScanManager( this ) );
new Pipeline( this );