- 
    Bug 
- 
    Resolution: Done
- 
    P2: Important 
- 
    4.7.0
- 
    None
- 
    Windows XP SP3.
 Intel dual core CPU.
- 
        0570a0f3936a2f7d7ec5afef9fcea8193ef3c15c (4.8), aee4cbf22a5942c7bd4b9545a8fcb7cf2930e0ee (5.0)
Calling directly QNetworkProxyFactory::systemProxyForQuery() can deadlock with QNetworkAccessManager methods when multiple threads are used.
Thread 1: calling QNetworkProxyFactory::systemProxyForQuery()
Thread 2: calling QNetworkAccessManager::get()
With suitable timing, the two threads become deadlocked.
in QNetworkProxyFactory::systemProxyForQuery(), thread 1 gets QWindowsSystemProxy, and locks a mutex in it. Few steps further, thread 1 gets to QGlobalNetworkProxy::init(), which is protected by a mutex in QGlobalNetworkProxy.
Meanwhile in thread 2, the QNetworkAccessManager::get() proceeds to QGlobalNetworkProxy::proxyForQuery, which locks the mutex in QGlobalNetworkProxy. Few calls later, thread 2 ends up in QNetworkProxyFactory::systemProxyForQuery(). But the mutex there is already locked by thread1, which is now waiting on the QGlobalNetworkProxy mutex which was locked by thread 2.
Thread 1:
 	QtCore4.dll!QMutexPrivate::wait(int timeout=0xffffffff)  Line 63 + 0x16 bytes	C++
 	QtCore4.dll!QMutex::lock()  Line 172	C++
 	QtCore4.dll!QMutexLocker::QMutexLocker(QMutex * m=0x01ba6b20)  Line 103	C++
 	QtNetwork4.dll!QGlobalNetworkProxy::init()  Line 260	C++
 	QtNetwork4.dll!QNetworkProxy::QNetworkProxy(QNetworkProxy::ProxyType type=HttpProxy, const QString & hostName="**.*.*.**", unsigned short port=0x1f90, const QString & user="", const QString & password="")  Line 445	C++
 	QtNetwork4.dll!parseServerList(const QNetworkProxyQuery & query=
> QtNetwork4.dll!QNetworkProxyFactory::systemProxyForQuery(const QNetworkProxyQuery & query={...}
) Line 394 + 0x10 bytes C++
Thread 2:
>	QtCore4.dll!QMutexPrivate::wait(int timeout=0xffffffff)  Line 63 + 0x16 bytes	C++
 	QtCore4.dll!QMutex::lock()  Line 209	C++
 	QtCore4.dll!QMutexLocker::QMutexLocker(QMutex * m=0x05d5be20)  Line 103	C++
 	QtNetwork4.dll!QNetworkProxyFactory::systemProxyForQuery(const QNetworkProxyQuery & query=
QtNetwork4.dll!QSystemConfigurationProxyFactory::queryProxy(const QNetworkProxyQuery & query={...}
)  Line 68 + 0x13 bytes	C++
 	QtNetwork4.dll!QGlobalNetworkProxy::proxyForQuery(const QNetworkProxyQuery & query=
QtNetwork4.dll!QNetworkProxyFactory::proxyForQuery(const QNetworkProxyQuery & query={...}
)  Line 1303 + 0x16 bytes	C++
 	QtNetwork4.dll!QNetworkAccessManagerPrivate::queryProxy(const QNetworkProxyQuery & query=
QtNetwork4.dll!QNetworkAccessManager::createRequest(QNetworkAccessManager::Operation op=0x05d5e5f8, const QNetworkRequest & req={...}
, QIODevice * outgoingData=0x00000000)  Line 1027 + 0x37 bytes	C++
 	QtNetwork4.dll!QNetworkAccessManager::get(const QNetworkRequest & request=
)  Line 688 + 0x14 bytes	C++
 	QtDeclarative4.dll!QDeclarativeImageRequestHandler::event(QEvent * event=0x05d5c000)  Line 289	C++