From 4a1bcc63cd2919f74f29b41c7b000f80da7449f4 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Thu, 31 Aug 2017 13:57:25 -0600 Subject: Avoid non threadsafe initialization. local static initialization is only threadsafe if initialized on construction. The other codepath is not threadsafe, but is only used in testcode. --- common/definitions.cpp | 18 +++++++++++++----- common/definitions.h | 8 +++++++- 2 files changed, 20 insertions(+), 6 deletions(-) (limited to 'common') diff --git a/common/definitions.cpp b/common/definitions.cpp index 17977bc..ee18d52 100644 --- a/common/definitions.cpp +++ b/common/definitions.cpp @@ -39,11 +39,17 @@ QString Sink::storageLocation() return dataLocation() + "/storage"; } +static QString sinkLocation(QStandardPaths::StandardLocation location) +{ + return QStandardPaths::writableLocation(location) + "/sink"; +} + QString Sink::dataLocation() { - static QString location; + static QString location = sinkLocation(QStandardPaths::GenericDataLocation); + //Warning: This is not threadsafe, but clearLocationCache is only ever used in testcode. The initialization above is required to make at least the initialization threadsafe (relies on C++11 threadsafe initialization). if (rereadDataLocation) { - location = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/sink"; + location = sinkLocation(QStandardPaths::GenericDataLocation); rereadDataLocation = false; } return location; @@ -51,9 +57,10 @@ QString Sink::dataLocation() QString Sink::configLocation() { - static QString location; + static QString location = sinkLocation(QStandardPaths::GenericConfigLocation); + //Warning: This is not threadsafe, but clearLocationCache is only ever used in testcode. The initialization above is required to make at least the initialization threadsafe (relies on C++11 threadsafe initialization). if (rereadConfigLocation) { - location = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/sink"; + location = sinkLocation(QStandardPaths::GenericConfigLocation); rereadConfigLocation = false; } return location; @@ -61,8 +68,9 @@ QString Sink::configLocation() QString Sink::temporaryFileLocation() { - static QString location; + static QString location = dataLocation() + "/temporaryFiles"; static bool dirCreated = false; + //Warning: This is not threadsafe, but clearLocationCache is only ever used in testcode. The initialization above is required to make at least the initialization threadsafe (relies on C++11 threadsafe initialization). if (rereadTemporaryFileLocation) { location = dataLocation() + "/temporaryFiles"; dirCreated = QDir{}.mkpath(location); diff --git a/common/definitions.h b/common/definitions.h index ce9e794..7ef215b 100644 --- a/common/definitions.h +++ b/common/definitions.h @@ -25,10 +25,16 @@ #include namespace Sink { -void SINK_EXPORT clearLocationCache(); QString SINK_EXPORT storageLocation(); QString SINK_EXPORT dataLocation(); QString SINK_EXPORT configLocation(); QString SINK_EXPORT temporaryFileLocation(); QString SINK_EXPORT resourceStorageLocation(const QByteArray &resourceInstanceIdentifier); + +/** + * Clear the location cache and lookup locations again. + * + * Warning: Calling this results in non-threadsafe initialization, only use it in test-code. + */ +void SINK_EXPORT clearLocationCache(); } -- cgit v1.2.3