summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2012-08-06 16:07:38 +0200
committerQt by Nokia <qt-info@nokia.com>2012-08-07 08:53:42 +0200
commit39c2fdd9070f81705f1de927694b8589f69da149 (patch)
tree9798334ca22aed7a367e1328c7fe735213944b4f
parent4ec169a60f9270a9ba673857de90e3b38ac94e7c (diff)
QWindowSystemInterface: fix mem leak and race
There was a race where QGuiApplicationPrivate::processMouseEvent accessed QWindowSystemInterfacePrivate::windowSystemEventQueue without holding QWindowSystemInterfacePrivate::queueMutex. There was a memory leak where QWindowSystemInterfacePrivate::windowSystemEventQueue would not delete events contained in it when it was destroyed. Fix both of these by properly encapsulating the QList/QMutex pair in a small class, WindowSystemEventList, that allows only properly protected access to the internal QList and calls qDeleteAll() in its dtor. Change-Id: Ifaa9968c9272096df2f7109a7a6cf1c8e5fa736c Reviewed-by: David Faure <faure@kde.org> Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp19
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h25
2 files changed, 26 insertions, 18 deletions
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index f97dcdf7f3..23c23ba159 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -58,8 +58,7 @@ QElapsedTimer QWindowSystemInterfacePrivate::eventTime;
// Callback functions for plugins:
//
-QList<QWindowSystemInterfacePrivate::WindowSystemEvent *> QWindowSystemInterfacePrivate::windowSystemEventQueue;
-QMutex QWindowSystemInterfacePrivate::queueMutex;
+QWindowSystemInterfacePrivate::WindowSystemEventList QWindowSystemInterfacePrivate::windowSystemEventQueue;
extern QPointer<QWindow> qt_last_mouse_receiver;
@@ -330,29 +329,17 @@ QWindowSystemInterfacePrivate::ExposeEvent::ExposeEvent(QWindow *exposed, const
int QWindowSystemInterfacePrivate::windowSystemEventsQueued()
{
- queueMutex.lock();
- int ret = windowSystemEventQueue.count();
- queueMutex.unlock();
- return ret;
+ return windowSystemEventQueue.count();
}
QWindowSystemInterfacePrivate::WindowSystemEvent * QWindowSystemInterfacePrivate::getWindowSystemEvent()
{
- queueMutex.lock();
- QWindowSystemInterfacePrivate::WindowSystemEvent *ret;
- if (windowSystemEventQueue.isEmpty())
- ret = 0;
- else
- ret = windowSystemEventQueue.takeFirst();
- queueMutex.unlock();
- return ret;
+ return windowSystemEventQueue.takeFirstOrReturnNull();
}
void QWindowSystemInterfacePrivate::queueWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *ev)
{
- queueMutex.lock();
windowSystemEventQueue.append(ev);
- queueMutex.unlock();
QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::qt_qpa_core_dispatcher();
if (dispatcher)
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index 26f4cd68bb..f39e473b29 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -45,6 +45,8 @@
#include <QElapsedTimer>
#include <QPointer>
+#include <QMutex>
+#include <QList>
QT_BEGIN_HEADER
@@ -323,8 +325,27 @@ public:
qint64 uid;
};
- static QList<WindowSystemEvent *> windowSystemEventQueue;
- static QMutex queueMutex;
+ class WindowSystemEventList {
+ QList<WindowSystemEvent *> impl;
+ mutable QMutex mutex;
+ public:
+ WindowSystemEventList() : impl(), mutex() {}
+ ~WindowSystemEventList()
+ { const QMutexLocker locker(&mutex); qDeleteAll(impl); impl.clear(); }
+
+ void prepend(WindowSystemEvent *e)
+ { const QMutexLocker locker(&mutex); impl.prepend(e); }
+ WindowSystemEvent *takeFirstOrReturnNull()
+ { const QMutexLocker locker(&mutex); return impl.empty() ? 0 : impl.takeFirst(); }
+ void append(WindowSystemEvent *e)
+ { const QMutexLocker locker(&mutex); impl.append(e); }
+ int count() const
+ { const QMutexLocker locker(&mutex); return impl.count(); }
+ private:
+ Q_DISABLE_COPY(WindowSystemEventList);
+ };
+
+ static WindowSystemEventList windowSystemEventQueue;
static int windowSystemEventsQueued();
static WindowSystemEvent * getWindowSystemEvent();