From 8bada697d6b8d7202e7975d73a5845c999fac8b2 Mon Sep 17 00:00:00 2001 From: Ievgenii Meshcheriakov Date: Wed, 31 Aug 2022 10:25:23 +0200 Subject: QTlsBackendOpenSSL: Early return from ensureCiphersAndCertsLoaded() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an atomic state variable to perform early return without taking a recursive lock after ensureCiphersAndCertsLoaded() is complete. Make related mutex and state variable function-local static because they are not used anywhere else. Taks-number: QTBUG-103559 Change-Id: I1e4c9c4f73204885bce82ba7f2b5e64548c3aac3 Reviewed-by: MÃ¥rten Nordheim --- src/plugins/tls/openssl/qtlsbackend_openssl.cpp | 22 ++++++++++++++++------ src/plugins/tls/openssl/qtlsbackend_openssl_p.h | 1 - 2 files changed, 16 insertions(+), 7 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/tls/openssl/qtlsbackend_openssl.cpp b/src/plugins/tls/openssl/qtlsbackend_openssl.cpp index b454a20f2a..dfd48e01af 100644 --- a/src/plugins/tls/openssl/qtlsbackend_openssl.cpp +++ b/src/plugins/tls/openssl/qtlsbackend_openssl.cpp @@ -33,8 +33,6 @@ using namespace Qt::StringLiterals; Q_LOGGING_CATEGORY(lcTlsBackend, "qt.tlsbackend.ossl"); -Q_GLOBAL_STATIC(QRecursiveMutex, qt_opensslInitMutex) - static void q_loadCiphersForConnection(SSL *connection, QList &ciphers, QList &defaultCiphers) { @@ -59,7 +57,6 @@ static void q_loadCiphersForConnection(SSL *connection, QList &ciphe } } -bool QTlsBackendOpenSSL::s_loadedCiphersAndCerts = false; int QTlsBackendOpenSSL::s_indexForSSLExtraData = -1; QString QTlsBackendOpenSSL::getErrorsFromOpenSsl() @@ -172,11 +169,24 @@ void QTlsBackendOpenSSL::ensureInitialized() const void QTlsBackendOpenSSL::ensureCiphersAndCertsLoaded() const { - const QMutexLocker locker(qt_opensslInitMutex()); + Q_CONSTINIT static bool initializationStarted = false; + Q_CONSTINIT static QAtomicInt initialized = Q_BASIC_ATOMIC_INITIALIZER(0); + Q_CONSTINIT static QRecursiveMutex initMutex; + + if (initialized.loadAcquire()) + return; - if (s_loadedCiphersAndCerts) + const QMutexLocker locker(&initMutex); + + if (initializationStarted || initialized.loadAcquire()) return; - s_loadedCiphersAndCerts = true; + + // Indicate that the initialization has already started in the current + // thread in case of recursive calls. The atomic variable cannot be used + // for this because it is checked without holding the init mutex. + initializationStarted = true; + + auto guard = qScopeGuard([] { initialized.storeRelease(1); }); resetDefaultCiphers(); resetDefaultEllipticCurves(); diff --git a/src/plugins/tls/openssl/qtlsbackend_openssl_p.h b/src/plugins/tls/openssl/qtlsbackend_openssl_p.h index 6ff1052957..b9f1f95df0 100644 --- a/src/plugins/tls/openssl/qtlsbackend_openssl_p.h +++ b/src/plugins/tls/openssl/qtlsbackend_openssl_p.h @@ -42,7 +42,6 @@ public: static void clearErrorQueue(); // Index used in SSL_get_ex_data to get the matching TlsCryptographerOpenSSL: - static bool s_loadedCiphersAndCerts; static int s_indexForSSLExtraData; static QString msgErrorsDuringHandshake(); -- cgit v1.2.3