From b188d9481b98680deb7f44fb41f8eafce18aedab Mon Sep 17 00:00:00 2001 From: Jian Liang Date: Mon, 14 Jan 2013 10:39:56 +0800 Subject: Fix QOpenGLContextGroup object leak MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-29056 QOpenGLContextGroup object is designed to be destroyed by deleteLater(), but this method will not always work due to the fact that in many cases event loop will exit before the deferred deletion of the QOpenGLContextGroup object is queued. Think about the following case: int main(int argc, char *argv[]) { QApplication a(argc, argv); QGLWidget w; w.show(); return a.exec(); } In the above program, the event loop will exit before QGLWidget object's destruction. This will cause the QOpenGLContextGroup object hold by QGLWidget object never been deleted. This patch will delete QOpenGLContextGroup object directly with delete operator if the current thread is the same as the thread which the QOpenGLContextGroup lives in. Change-Id: If835d7482474f4a668763fc7c21b293a27f075fd Reviewed-by: Samuel Rødal Reviewed-by: Sean Harmer --- src/gui/kernel/qopenglcontext.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index f16f29718d..96b09342c7 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -759,15 +759,26 @@ void QOpenGLContextGroupPrivate::removeContext(QOpenGLContext *ctx) { Q_Q(QOpenGLContextGroup); - QMutexLocker locker(&m_mutex); - m_shares.removeOne(ctx); + bool deleteObject = false; + + { + QMutexLocker locker(&m_mutex); + m_shares.removeOne(ctx); - if (ctx == m_context && !m_shares.isEmpty()) - m_context = m_shares.first(); + if (ctx == m_context && !m_shares.isEmpty()) + m_context = m_shares.first(); + + if (!m_refs.deref()) { + cleanup(); + deleteObject = true; + } + } - if (!m_refs.deref()) { - cleanup(); - q->deleteLater(); + if (deleteObject) { + if (q->thread() == QThread::currentThread()) + delete q; // Delete directly to prevent leak, refer to QTBUG-29056 + else + q->deleteLater(); } } -- cgit v1.2.3