Fix QOpenGLContextGroup object leak

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 <samuel.rodal@digia.com>
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
This commit is contained in:
Jian Liang 2013-01-14 10:39:56 +08:00 committed by The Qt Project
parent 4bd4c811f2
commit b188d9481b

View File

@ -759,15 +759,26 @@ void QOpenGLContextGroupPrivate::removeContext(QOpenGLContext *ctx)
{
Q_Q(QOpenGLContextGroup);
QMutexLocker locker(&m_mutex);
m_shares.removeOne(ctx);
bool deleteObject = false;
if (ctx == m_context && !m_shares.isEmpty())
m_context = m_shares.first();
{
QMutexLocker locker(&m_mutex);
m_shares.removeOne(ctx);
if (!m_refs.deref()) {
cleanup();
q->deleteLater();
if (ctx == m_context && !m_shares.isEmpty())
m_context = m_shares.first();
if (!m_refs.deref()) {
cleanup();
deleteObject = true;
}
}
if (deleteObject) {
if (q->thread() == QThread::currentThread())
delete q; // Delete directly to prevent leak, refer to QTBUG-29056
else
q->deleteLater();
}
}