Make the named QColorSpace constructor thread-safe
Avoid accessing the shared pointer table without using atomic. Cleans up the shared table on exit for leak tracking utilities. Pick-to: 5.15 Change-Id: Ia2d6d79dea1c8be02bae2d8111e290f49eedf409 Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
This commit is contained in:
parent
1613eff15e
commit
cd0b5bba9a
@ -46,6 +46,7 @@
|
||||
#include "qcolortransform_p.h"
|
||||
#include "qicc_p.h"
|
||||
|
||||
#include <qatomic.h>
|
||||
#include <qmath.h>
|
||||
#include <qtransform.h>
|
||||
|
||||
@ -55,6 +56,18 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
QBasicMutex QColorSpacePrivate::s_lutWriteLock;
|
||||
|
||||
static QAtomicPointer<QColorSpacePrivate> s_predefinedColorspacePrivates[QColorSpace::ProPhotoRgb] = {};
|
||||
static void cleanupPredefinedColorspaces()
|
||||
{
|
||||
for (QAtomicPointer<QColorSpacePrivate> &ptr : s_predefinedColorspacePrivates) {
|
||||
QColorSpacePrivate *prv = ptr.fetchAndStoreAcquire(nullptr);
|
||||
if (prv && !prv->ref.deref())
|
||||
delete prv;
|
||||
}
|
||||
}
|
||||
|
||||
Q_DESTRUCTOR_FUNCTION(cleanupPredefinedColorspaces)
|
||||
|
||||
QColorSpacePrimaries::QColorSpacePrimaries(QColorSpace::Primaries primaries)
|
||||
{
|
||||
switch (primaries) {
|
||||
@ -426,12 +439,18 @@ QColorSpace::QColorSpace(NamedColorSpace namedColorSpace)
|
||||
qWarning() << "QColorSpace attempted constructed from invalid QColorSpace::NamedColorSpace: " << int(namedColorSpace);
|
||||
return;
|
||||
}
|
||||
static QColorSpacePrivate *predefinedColorspacePrivates[QColorSpace::ProPhotoRgb + 1];
|
||||
if (!predefinedColorspacePrivates[namedColorSpace]) {
|
||||
predefinedColorspacePrivates[namedColorSpace] = new QColorSpacePrivate(namedColorSpace);
|
||||
predefinedColorspacePrivates[namedColorSpace]->ref.ref();
|
||||
// The defined namespaces start at 1:
|
||||
auto &atomicRef = s_predefinedColorspacePrivates[static_cast<int>(namedColorSpace) - 1];
|
||||
QColorSpacePrivate *cspriv = atomicRef.loadAcquire();
|
||||
if (!cspriv) {
|
||||
auto *tmp = new QColorSpacePrivate(namedColorSpace);
|
||||
tmp->ref.ref();
|
||||
if (atomicRef.testAndSetOrdered(nullptr, tmp, cspriv))
|
||||
cspriv = tmp;
|
||||
else
|
||||
delete tmp;
|
||||
}
|
||||
d_ptr = predefinedColorspacePrivates[namedColorSpace];
|
||||
d_ptr = cspriv;
|
||||
d_ptr->ref.ref();
|
||||
Q_ASSERT(isValid());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user