Skip to content
Permalink
Browse files

Fix random stall in QgsBlockingNetworkRequest at QGIS exit

which prevents the application from exiting (GUI remains blocked)

This fixes a 'random' issue (occurs maybe 20% of the time I try to reproduce it)
when a vector layer using QgsBlockingNetworkRequest is running in a map renderer
job when QGIS exits. The scenario I use involves adding an Elasticsearch OGR layer,
zooming in/out a bit (not sure it is needed), saving the project, and within
a few tens of second later (maybe 0.1 to 0.5s later) clicking on the close
window button (timing is tricky...)

The stacktrace of when it stalls is below. So for some reason the QEventLoop of
QgsBlockingNetworkRequest never exits (not even when the timeout of network requests
expires).
When adding a version of this patch with a print statement in the slot, I could see
that the aboutToQuit() signal is triggered sometimes, and I can no longer reproduce
the stalls.

(gdb) bt
0  pthread_cond_wait@@GLIBC_2.3.2 () at ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
1  0x00007ffff18ab5bb in QWaitCondition::wait(QMutex*, unsigned long) () from /opt/qt59/lib/libQt5Core.so.5
2  0x00007ffff18a60d5 in QThreadPoolPrivate::waitForDone(int) () from /opt/qt59/lib/libQt5Core.so.5
3  0x00007ffff18a6491 in QThreadPool::waitForDone(int) () from /opt/qt59/lib/libQt5Core.so.5
4  0x00007ffff3791102 in QgsApplication::exitQgis () at /home/even/qgis/QGIS/src/core/qgsapplication.cpp:1309
5  0x00007ffff6f6b4f0 in QgisApp::~QgisApp (this=0xc20920, __in_chrg=<optimized out>) at /home/even/qgis/QGIS/src/app/qgisapp.cpp:1889
6  0x00007ffff6f6b740 in QgisApp::~QgisApp (this=0xc20920, __in_chrg=<optimized out>) at /home/even/qgis/QGIS/src/app/qgisapp.cpp:1891
7  0x00000000004161ad in main (argc=1, argv=0x7fffffffd798) at /home/even/qgis/QGIS/src/app/main.cpp:1638
(gdb) thread apply all bt

Thread 6 (Thread 0x7fffaa52f700 (LWP 24484)):
0  0x00007ffff0f3280d in poll () at ../sysdeps/unix/syscall-template.S:84
1  0x00007fffe7f4d38c in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
2  0x00007fffe7f4d49c in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
3  0x00007ffff1adf29f in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /opt/qt59/lib/libQt5Core.so.5
4  0x00007ffff1a8813a in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /opt/qt59/lib/libQt5Core.so.5
5  0x00007ffff37c2b8a in QgsBlockingNetworkRequest::<lambda()>::operator()(void) const (__closure=0x7fff9c0e12d0) at /home/even/qgis/QGIS/src/core/qgsblockingnetworkrequest.cpp:203
6  0x00007ffff37c560c in std::_Function_handler<void(), QgsBlockingNetworkRequest::doRequest(QgsBlockingNetworkRequest::Method, QNetworkRequest&, bool, QgsFeedback*)::<lambda()> >::_M_invoke(const std::_Any_data &) (__functor=...) at /usr/include/c++/5/functional:1871
7  0x00007ffff318a868 in std::function<void ()>::operator()() const (this=0x7fffaa527a40) at /usr/include/c++/5/functional:2267
8  0x00007ffff37c339b in QgsBlockingNetworkRequest::doRequest (this=0x7fffaa527c60, method=QgsBlockingNetworkRequest::Get, request=..., forceRefresh=true, feedback=0x7fff9c0d4980)
    at /home/even/qgis/QGIS/src/core/qgsblockingnetworkrequest.cpp:252
9  0x00007ffff37c2327 in QgsBlockingNetworkRequest::get (this=0x7fffaa527c60, request=..., forceRefresh=true, feedback=0x7fff9c0d4980) at /home/even/qgis/QGIS/src/core/qgsblockingnetworkrequest.cpp:59
10 0x00007ffff388f1c3 in QgsCPLHTTPFetchOverrider::callback (
    pszURL=0x7fff9c19da90 "http://localhost:9201/_search/scroll?scroll=1m&scroll_id=FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFEM1Y0gzblVCTkVidlF6YlJnUC1DAAAAAAAAA9cWTFBzeGVGZXpSZ3VXOUlkazhYM0Rvdw==",
    papszOptions=0x0, pfnWrite=0x0, pWriteArg=0x0, pUserData=0x7fffaa528620) at /home/even/qgis/QGIS/src/core/qgscplhttpfetchoverrider.cpp:139
--Type <RET> for more, q to quit, c to continue without paging--
11 0x00007fffef3ddf96 in CPLHTTPFetchEx (
    pszURL=0x7fff9c19da90 "http://localhost:9201/_search/scroll?scroll=1m&scroll_id=FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFEM1Y0gzblVCTkVidlF6YlJnUC1DAAAAAAAAA9cWTFBzeGVGZXpSZ3VXOUlkazhYM0Rvdw==",
    papszOptions=0x0, pfnProgress=0x0, pProgressArg=0x0, pfnWrite=0x0, pWriteArg=0x0) at cpl_http.cpp:1081
12 0x00007fffef3dd9f6 in CPLHTTPFetch (
    pszURL=0x7fff9c19da90 "http://localhost:9201/_search/scroll?scroll=1m&scroll_id=FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFEM1Y0gzblVCTkVidlF6YlJnUC1DAAAAAAAAA9cWTFBzeGVGZXpSZ3VXOUlkazhYM0Rvdw==",
    papszOptions=0x0) at cpl_http.cpp:972
13 0x00007fffef885cfd in OGRElasticDataSource::HTTPFetch (this=0x7fff9c094180,
    pszURL=0x7fff9c19da90 "http://localhost:9201/_search/scroll?scroll=1m&scroll_id=FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFEM1Y0gzblVCTkVidlF6YlJnUC1DAAAAAAAAA9cWTFBzeGVGZXpSZ3VXOUlkazhYM0Rvdw==",
    papszOptions=0x0) at ogrelasticdatasource.cpp:590
14 0x00007fffef885e19 in OGRElasticDataSource::RunRequest (this=0x7fff9c094180,
    pszURL=0x7fff9c19da90 "http://localhost:9201/_search/scroll?scroll=1m&scroll_id=FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFEM1Y0gzblVCTkVidlF6YlJnUC1DAAAAAAAAA9cWTFBzeGVGZXpSZ3VXOUlkazhYM0Rvdw==",
    pszPostContent=0x7fffaa5283b0 "", anSilentedHTTPErrors=std::vector of length 0, capacity 0) at ogrelasticdatasource.cpp:612
15 0x00007fffef891f52 in OGRElasticLayer::GetNextRawFeature (this=0x7fff9c0932e0) at ogrelasticlayer.cpp:1159
16 0x00007fffef891245 in OGRElasticLayer::GetNextFeature (this=0x7fff9c0932e0) at ogrelasticlayer.cpp:995
17 0x00007fffef9ecd35 in OGR_L_GetNextFeature (hLayer=0x7fff9c0932e0) at ogrlayer.cpp:551
18 0x00007ffff3712b71 in QgsOgrFeatureIterator::fetchFeature (this=0x7fff9c0cf5d0, feature=...) at /home/even/qgis/QGIS/src/core/providers/ogr/qgsogrfeatureiterator.cpp:400
19 0x00007ffff390431c in QgsAbstractFeatureIterator::nextFeature (this=0x7fff9c0cf5d0, f=...) at /home/even/qgis/QGIS/src/core/qgsfeatureiterator.cpp:63
20 0x00007ffff7018a24 in QgsFeatureIterator::nextFeature (this=0x7fff9c0cf390, f=...) at /home/even/qgis/QGIS/src/core/qgsfeatureiterator.h:376
21 0x00007ffff3c5bda4 in QgsVectorLayerFeatureIterator::fetchFeature (this=0x7fff9c0cf150, f=...) at /home/even/qgis/QGIS/src/core/qgsvectorlayerfeatureiterator.cpp:442
22 0x00007ffff390431c in QgsAbstractFeatureIterator::nextFeature (this=0x7fff9c0cf150, f=...) at /home/even/qgis/QGIS/src/core/qgsfeatureiterator.cpp:63
23 0x00007ffff7018a24 in QgsFeatureIterator::nextFeature (this=0x7fffaa528aa0, f=...) at /home/even/qgis/QGIS/src/core/qgsfeatureiterator.h:376
24 0x00007ffff3c7443d in QgsVectorLayerRenderer::drawRenderer (this=0x4e07480, fit=...) at /home/even/qgis/QGIS/src/core/qgsvectorlayerrenderer.cpp:346
25 0x00007ffff3c73d43 in QgsVectorLayerRenderer::render (this=0x4e07480) at /home/even/qgis/QGIS/src/core/qgsvectorlayerrenderer.cpp:315
26 0x00007ffff39c724e in QgsMapRendererCustomPainterJob::doRender (this=0x4dbd3b0) at /home/even/qgis/QGIS/src/core/qgsmaprenderercustompainterjob.cpp:317
27 0x00007ffff39c6cce in QgsMapRendererCustomPainterJob::staticRender (self=0x4dbd3b0) at /home/even/qgis/QGIS/src/core/qgsmaprenderercustompainterjob.cpp:267
28 0x00007ffff39ca485 in QtConcurrent::StoredFunctorCall1<void, void (*)(QgsMapRendererCustomPainterJob*), QgsMapRendererCustomPainterJob*>::runFunctor (this=0x4d435f0)
    at /opt/qt59/include/QtConcurrent/qtconcurrentstoredfunctioncall.h:432
29 0x00007ffff39c7e9d in QtConcurrent::RunFunctionTask<void>::run (this=0x4d435f0) at /opt/qt59/include/QtConcurrent/qtconcurrentrunbase.h:136
30 0x00007ffff18a6943 in ?? () from /opt/qt59/lib/libQt5Core.so.5
31 0x00007ffff18aa659 in ?? () from /opt/qt59/lib/libQt5Core.so.5
32 0x00007fffe93dc6ba in start_thread (arg=0x7fffaa52f700) at pthread_create.c:333
33 0x00007ffff0f3e4dd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109
  • Loading branch information
rouault authored and nyalldawson committed Nov 19, 2020
1 parent c7bdc47 commit a689043be7af6a7d0ff1529aa459e668aa33758f
Showing with 4 additions and 0 deletions.
  1. +4 −0 src/core/qgsblockingnetworkrequest.cpp
@@ -199,6 +199,10 @@ QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::doRequest( QgsBl
#endif
}
QEventLoop loop;
// connecting to aboutToQuit avoids an on-going request to remain stalled
// when QThreadPool::globalInstance()->waitForDone()
// is called at process termination
connect( qApp, &QCoreApplication::aboutToQuit, &loop, &QEventLoop::quit, Qt::DirectConnection );
connect( this, &QgsBlockingNetworkRequest::downloadFinished, &loop, &QEventLoop::quit, Qt::DirectConnection );
loop.exec();
}

0 comments on commit a689043

Please sign in to comment.
You can’t perform that action at this time.