QNAM: work around QObject finicky orphan cleanup details
authorDebian Qt/KDE Maintainers <debian-qt-kde@lists.debian.org>
Sun, 28 Nov 2021 14:12:50 +0000 (14:12 +0000)
committerDmitry Shachnev <mitya57@debian.org>
Sun, 28 Nov 2021 14:12:50 +0000 (14:12 +0000)
Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=0807f16eb407eaf8
Last-Update: 2021-01-26

Gbp-Pq: Name qnam_connect_memory_leak.diff

src/network/access/qnetworkreplyhttpimpl.cpp

index 21916f53f151f90738513696f24311bd031ae16a..727c1a0316d76091ecc6d07c440c2189c3f5b32c 100644 (file)
@@ -808,7 +808,17 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq
 
     // For the synchronous HTTP, this is the normal way the delegate gets deleted
     // For the asynchronous HTTP this is a safety measure, the delegate deletes itself when HTTP is finished
-    QObject::connect(thread, SIGNAL(finished()), delegate, SLOT(deleteLater()));
+    QMetaObject::Connection threadFinishedConnection =
+            QObject::connect(thread, SIGNAL(finished()), delegate, SLOT(deleteLater()));
+
+    // QTBUG-88063: When 'delegate' is deleted the connection will be added to 'thread''s orphaned
+    // connections list. This orphaned list will be cleaned up next time 'thread' emits a signal,
+    // unfortunately that's the finished signal. It leads to a soft-leak so we do this to disconnect
+    // it on deletion so that it cleans up the orphan immediately.
+    QObject::connect(delegate, &QObject::destroyed, delegate, [threadFinishedConnection]() {
+        if (bool(threadFinishedConnection))
+            QObject::disconnect(threadFinishedConnection);
+    });
 
     // Set the properties it needs
     delegate->httpRequest = httpRequest;