diff options
author | Shane Kearns <ext-shane.2.kearns@nokia.com> | 2012-02-29 15:53:24 (GMT) |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-03-04 14:35:17 (GMT) |
commit | 656fab5e848fd14e5d00536a4babbb2f33dbcfb7 (patch) | |
tree | 607a05515e81d2ba9f46dcb3ea609ac0a0217c7d /src/network | |
parent | 8108650b24adbe03543eb29015ea9bda86d0068e (diff) | |
download | Qt-656fab5e848fd14e5d00536a4babbb2f33dbcfb7.zip Qt-656fab5e848fd14e5d00536a4babbb2f33dbcfb7.tar.gz Qt-656fab5e848fd14e5d00536a4babbb2f33dbcfb7.tar.bz2 |
QSslCertificate - make lazy initialisation thread safe
QSslCertificate can be copied around into multiple threads,
without detaching. For example, the https worker threads inside
QNetworkAccessManager.
There are const methods, which lazily initialise members of
the private class without detaching (i.e. caching results of
expensive function calls)
These functions now lock the d pointer using QMutexPool to
avoid concurrency related crashes.
autotest crashes 20% of the time in release builds without
the fix, passes 100 times in a row with the fix.
Task-number: QTBUG-20452
Change-Id: I64a01af8159216f2dd6215a08669890f6c029ca8
(cherry picked from commit 55bf4ed9468ad467a0b681d2d041edbc2a5a4d21)
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/ssl/qsslcertificate.cpp | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index 2edb202..dca37dd 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -121,6 +121,8 @@ #include <QtCore/qfile.h> #include <QtCore/qfileinfo.h> #include <QtCore/qmap.h> +#include <QtCore/qmutex.h> +#include <QtCore/private/qmutexpool_p.h> #include <QtCore/qstring.h> #include <QtCore/qstringlist.h> @@ -252,6 +254,7 @@ void QSslCertificate::clear() */ QByteArray QSslCertificate::version() const { + QMutexLocker lock(QMutexPool::globalInstanceGet(d.data())); if (d->versionString.isEmpty() && d->x509) d->versionString = QByteArray::number(qlonglong(q_ASN1_INTEGER_get(d->x509->cert_info->version)) + 1); @@ -267,6 +270,7 @@ QByteArray QSslCertificate::version() const */ QByteArray QSslCertificate::serialNumber() const { + QMutexLocker lock(QMutexPool::globalInstanceGet(d.data())); if (d->serialNumberString.isEmpty() && d->x509) { ASN1_INTEGER *serialNumber = d->x509->cert_info->serialNumber; // if we cannot convert to a long, just output the hexadecimal number @@ -321,6 +325,7 @@ static QString _q_SubjectInfoToString(QSslCertificate::SubjectInfo info) */ QString QSslCertificate::issuerInfo(SubjectInfo info) const { + QMutexLocker lock(QMutexPool::globalInstanceGet(d.data())); // lazy init if (d->issuerInfo.isEmpty() && d->x509) d->issuerInfo = @@ -338,6 +343,7 @@ QString QSslCertificate::issuerInfo(SubjectInfo info) const */ QString QSslCertificate::issuerInfo(const QByteArray &tag) const { + QMutexLocker lock(QMutexPool::globalInstanceGet(d.data())); // lazy init if (d->issuerInfo.isEmpty() && d->x509) d->issuerInfo = @@ -357,6 +363,7 @@ QString QSslCertificate::issuerInfo(const QByteArray &tag) const */ QString QSslCertificate::subjectInfo(SubjectInfo info) const { + QMutexLocker lock(QMutexPool::globalInstanceGet(d.data())); // lazy init if (d->subjectInfo.isEmpty() && d->x509) d->subjectInfo = @@ -373,6 +380,7 @@ QString QSslCertificate::subjectInfo(SubjectInfo info) const */ QString QSslCertificate::subjectInfo(const QByteArray &tag) const { + QMutexLocker lock(QMutexPool::globalInstanceGet(d.data())); // lazy init if (d->subjectInfo.isEmpty() && d->x509) d->subjectInfo = |