QTouchDevice: don't play ping-pong with q*PostRoutine()

Removing a qPostRoutine is an O(N) operation. It's perfectly ok to
keep calling it even if the list has become empty before.

Just qAddPostRoutine in the deviceList's ctor and never remove it
again.

Add a missing qAsConst as a drive-by.

Change-Id: I25f824b74012146214568cfccb22c5dba3ca38ef
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
This commit is contained in:
Marc Mutz 2019-08-23 09:51:39 +02:00
parent 65dfc485ad
commit e45e6efa72

View File

@ -44,6 +44,7 @@
#include <QCoreApplication> #include <QCoreApplication>
#include <private/qdebug_p.h> #include <private/qdebug_p.h>
#include <private/qlocking_p.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -201,15 +202,20 @@ void QTouchDevice::setName(const QString &name)
d->name = name; d->name = name;
} }
typedef QList<const QTouchDevice *> TouchDevices;
Q_GLOBAL_STATIC(TouchDevices, deviceList)
static QBasicMutex devicesMutex; static QBasicMutex devicesMutex;
static void cleanupDevicesList() struct TouchDevices {
TouchDevices();
QList<const QTouchDevice *> list;
};
Q_GLOBAL_STATIC(TouchDevices, deviceList)
TouchDevices::TouchDevices()
{ {
QMutexLocker lock(&devicesMutex); qAddPostRoutine([]{
qDeleteAll(*deviceList()); const auto locker = qt_scoped_lock(devicesMutex);
deviceList()->clear(); qDeleteAll(qExchange(deviceList->list, {}));
});
} }
/*! /*!
@ -223,7 +229,7 @@ static void cleanupDevicesList()
QList<const QTouchDevice *> QTouchDevice::devices() QList<const QTouchDevice *> QTouchDevice::devices()
{ {
QMutexLocker lock(&devicesMutex); QMutexLocker lock(&devicesMutex);
return *deviceList(); return deviceList->list;
} }
/*! /*!
@ -232,13 +238,13 @@ QList<const QTouchDevice *> QTouchDevice::devices()
bool QTouchDevicePrivate::isRegistered(const QTouchDevice *dev) bool QTouchDevicePrivate::isRegistered(const QTouchDevice *dev)
{ {
QMutexLocker locker(&devicesMutex); QMutexLocker locker(&devicesMutex);
return deviceList()->contains(dev); return deviceList->list.contains(dev);
} }
const QTouchDevice *QTouchDevicePrivate::deviceById(quint8 id) const QTouchDevice *QTouchDevicePrivate::deviceById(quint8 id)
{ {
QMutexLocker locker(&devicesMutex); QMutexLocker locker(&devicesMutex);
for (const QTouchDevice *dev : *deviceList()) for (const QTouchDevice *dev : qAsConst(deviceList->list))
if (QTouchDevicePrivate::get(const_cast<QTouchDevice *>(dev))->id == id) if (QTouchDevicePrivate::get(const_cast<QTouchDevice *>(dev))->id == id)
return dev; return dev;
return nullptr; return nullptr;
@ -250,9 +256,7 @@ const QTouchDevice *QTouchDevicePrivate::deviceById(quint8 id)
void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev) void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev)
{ {
QMutexLocker lock(&devicesMutex); QMutexLocker lock(&devicesMutex);
if (deviceList()->isEmpty()) deviceList->list.append(dev);
qAddPostRoutine(cleanupDevicesList);
deviceList()->append(dev);
} }
/*! /*!
@ -261,9 +265,7 @@ void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev)
void QTouchDevicePrivate::unregisterDevice(const QTouchDevice *dev) void QTouchDevicePrivate::unregisterDevice(const QTouchDevice *dev)
{ {
QMutexLocker lock(&devicesMutex); QMutexLocker lock(&devicesMutex);
bool wasRemoved = deviceList()->removeOne(dev); deviceList->list.removeOne(dev);
if (wasRemoved && deviceList()->isEmpty())
qRemovePostRoutine(cleanupDevicesList);
} }
#ifndef QT_NO_DEBUG_STREAM #ifndef QT_NO_DEBUG_STREAM