summaryrefslogtreecommitdiffstats
path: root/src/corelib/plugin/qlibrary_unix.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2019-12-18 18:45:36 -0800
committerThiago Macieira <thiago.macieira@intel.com>2020-03-03 14:36:32 -0800
commitae6f73e8566fa76470937aca737141183929a5ec (patch)
tree4a45798d9c4d6b1e5f163a4d215ce4988e76d1bc /src/corelib/plugin/qlibrary_unix.cpp
parentef92ac5636c2f0407fba8141c35ea61d391fd479 (diff)
QLibrary: introduce a mutex to protect non-atomic internals
And make pHnd atomic. The majority of the variables is updated in QLibraryPrivate::load_sys and updatePluginState(), which get the mutex protection. QLibraryPrivate::unload_sys() doesn't need a mutex protection because we have the refcounting. [ChangeLog][QtCore][QLibrary & QPluginLoader] Fixed a number of race conditions caused by having two QLibrary objects pointing to the same library being operated in different threads. Fixes: QTBUG-39642 Change-Id: I46bf1f65e8db46afbde5fffd15e1a5b3f5e74ea4 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/corelib/plugin/qlibrary_unix.cpp')
-rw-r--r--src/corelib/plugin/qlibrary_unix.cpp24
1 files changed, 13 insertions, 11 deletions
diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp
index 23f96dbdaf..29813e5863 100644
--- a/src/corelib/plugin/qlibrary_unix.cpp
+++ b/src/corelib/plugin/qlibrary_unix.cpp
@@ -214,8 +214,9 @@ bool QLibraryPrivate::load_sys()
#endif
bool retry = true;
- for(int prefix = 0; retry && !pHnd && prefix < prefixes.size(); prefix++) {
- for(int suffix = 0; retry && !pHnd && suffix < suffixes.size(); suffix++) {
+ Handle hnd = nullptr;
+ for (int prefix = 0; retry && !hnd && prefix < prefixes.size(); prefix++) {
+ for (int suffix = 0; retry && !hnd && suffix < suffixes.size(); suffix++) {
if (!prefixes.at(prefix).isEmpty() && name.startsWith(prefixes.at(prefix)))
continue;
if (path.isEmpty() && prefixes.at(prefix).contains(QLatin1Char('/')))
@@ -232,7 +233,7 @@ bool QLibraryPrivate::load_sys()
attempt = path + prefixes.at(prefix) + name + suffixes.at(suffix);
}
- pHnd = dlopen(QFile::encodeName(attempt), dlFlags);
+ hnd = dlopen(QFile::encodeName(attempt), dlFlags);
#ifdef Q_OS_ANDROID
if (!pHnd) {
auto attemptFromBundle = attempt;
@@ -248,7 +249,7 @@ bool QLibraryPrivate::load_sys()
}
#endif
- if (!pHnd && fileName.startsWith(QLatin1Char('/')) && QFile::exists(attempt)) {
+ if (!hnd && fileName.startsWith(QLatin1Char('/')) && QFile::exists(attempt)) {
// We only want to continue if dlopen failed due to that the shared library did not exist.
// However, we are only able to apply this check for absolute filenames (since they are
// not influenced by the content of LD_LIBRARY_PATH, /etc/ld.so.cache, DT_RPATH etc...)
@@ -259,7 +260,7 @@ bool QLibraryPrivate::load_sys()
}
#ifdef Q_OS_MAC
- if (!pHnd) {
+ if (!hnd) {
QByteArray utf8Bundle = fileName.toUtf8();
QCFType<CFURLRef> bundleUrl = CFURLCreateFromFileSystemRepresentation(NULL, reinterpret_cast<const UInt8*>(utf8Bundle.data()), utf8Bundle.length(), true);
QCFType<CFBundleRef> bundle = CFBundleCreate(NULL, bundleUrl);
@@ -268,23 +269,24 @@ bool QLibraryPrivate::load_sys()
char executableFile[FILENAME_MAX];
CFURLGetFileSystemRepresentation(url, true, reinterpret_cast<UInt8*>(executableFile), FILENAME_MAX);
attempt = QString::fromUtf8(executableFile);
- pHnd = dlopen(QFile::encodeName(attempt), dlFlags);
+ hnd = dlopen(QFile::encodeName(attempt), dlFlags);
}
}
#endif
- if (!pHnd) {
+ if (!hnd) {
errorString = QLibrary::tr("Cannot load library %1: %2").arg(fileName, qdlerror());
}
- if (pHnd) {
+ if (hnd) {
qualifiedFileName = attempt;
errorString.clear();
}
- return (pHnd != 0);
+ pHnd.storeRelaxed(hnd);
+ return (hnd != nullptr);
}
bool QLibraryPrivate::unload_sys()
{
- if (dlclose(pHnd)) {
+ if (dlclose(pHnd.loadAcquire())) {
#if defined (Q_OS_QNX) // Workaround until fixed in QNX; fixes crash in
char *error = dlerror(); // QtDeclarative auto test "qqmlenginecleanup" for instance
if (!qstrcmp(error, "Shared objects still referenced")) // On QNX that's only "informative"
@@ -316,7 +318,7 @@ Q_CORE_EXPORT QFunctionPointer qt_mac_resolve_sys(void *handle, const char *symb
QFunctionPointer QLibraryPrivate::resolve_sys(const char* symbol)
{
- QFunctionPointer address = QFunctionPointer(dlsym(pHnd, symbol));
+ QFunctionPointer address = QFunctionPointer(dlsym(pHnd.loadAcquire(), symbol));
return address;
}