diff options
author | Mårten Nordheim <marten.nordheim@qt.io> | 2021-02-17 09:54:48 +0100 |
---|---|---|
committer | Mårten Nordheim <marten.nordheim@qt.io> | 2021-02-18 12:27:50 +0000 |
commit | c98e92b8ca7fd295482ee99f095c220b6f389169 (patch) | |
tree | ac71e0e9b56a1a8b5a74a5d8af88b4354bfe0bde /src/network | |
parent | 15572f9efeb1b7dd609b55f8981eb5b5dc3d3db9 (diff) |
QNetworkInformation: Revise locking during creation
Potential issue caught by the Mårten static analyzer.
In case another thread somehow ended up creating and returning
an instance while another was waiting to relock it would deallocate
the previous instance, which could lead to some bad situations.
Pick-to: 6.1
Change-Id: I6e1843f8a483b2c3e0540e998c383e41f59c8655
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/kernel/qnetworkinformation.cpp | 19 |
1 files changed, 8 insertions, 11 deletions
diff --git a/src/network/kernel/qnetworkinformation.cpp b/src/network/kernel/qnetworkinformation.cpp index 9696a4fcc2..d10024bf05 100644 --- a/src/network/kernel/qnetworkinformation.cpp +++ b/src/network/kernel/qnetworkinformation.cpp @@ -168,22 +168,21 @@ QNetworkInformation *QNetworkInformationPrivate::create(QStringView name) { if (!dataHolder()) return nullptr; - QMutexLocker locker(&dataHolder->instanceMutex); #ifdef DEBUG_LOADING qDebug().nospace() << "create() called with name=\"" << name << "\". instanceHolder initialized? " << !!dataHolder->instanceHolder; #endif - if (dataHolder->instanceHolder) - return dataHolder->instanceHolder.get(); - - locker.unlock(); if (!initializeList()) { #ifdef DEBUG_LOADING qDebug("Failed to initialize list, returning."); #endif return nullptr; } - locker.relock(); + + QMutexLocker locker(&dataHolder->instanceMutex); + if (dataHolder->instanceHolder) + return dataHolder->instanceHolder.get(); + QNetworkInformationBackend *backend = nullptr; if (!name.isEmpty()) { @@ -231,24 +230,22 @@ QNetworkInformation *QNetworkInformationPrivate::create(QNetworkInformation::Fea { if (!dataHolder()) return nullptr; - QMutexLocker locker(&dataHolder->instanceMutex); #ifdef DEBUG_LOADING qDebug().nospace() << "create() called with features=\"" << features << "\". instanceHolder initialized? " << !!dataHolder->instanceHolder; #endif - if (dataHolder->instanceHolder) - return dataHolder->instanceHolder.get(); if (features == 0) return nullptr; - locker.unlock(); if (!initializeList()) { #ifdef DEBUG_LOADING qDebug("Failed to initialize list, returning."); #endif return nullptr; } - locker.relock(); + QMutexLocker locker(&dataHolder->instanceMutex); + if (dataHolder->instanceHolder) + return dataHolder->instanceHolder.get(); const auto supportsRequestedFeatures = [features](QNetworkInformationBackendFactory *factory) { return factory && (factory->featuresSupported() & features) == features; |