summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp6
-rw-r--r--src/corelib/plugin/qfactoryloader_p.h2
-rw-r--r--src/corelib/plugin/qlibrary_unix.cpp5
-rw-r--r--src/corelib/thread/qthread_unix.cpp12
4 files changed, 19 insertions, 6 deletions
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp
index 21e4c294c91..31abed73cf9 100644
--- a/src/corelib/plugin/qfactoryloader.cpp
+++ b/src/corelib/plugin/qfactoryloader.cpp
@@ -359,6 +359,11 @@ inline void QFactoryLoader::Private::updateSinglePath(const QString &path)
loadedLibraries.resize(libraries.size());
}
+void QFactoryLoader::setLoadHints(QLibrary::LoadHints loadHints)
+{
+ d->loadHints = loadHints;
+}
+
void QFactoryLoader::update()
{
#ifdef QT_SHARED
@@ -549,6 +554,7 @@ inline QObject *QFactoryLoader::instanceHelper_locked(int index) const
if (size_t(index) < d->libraries.size()) {
QLibraryPrivate *library = d->libraries[index].get();
d->loadedLibraries[index] = true;
+ library->setLoadHints(d->loadHints);
return library->pluginInstance();
}
// we know d->libraries.size() <= index <= numeric_limits<decltype(index)>::max() → no overflow
diff --git a/src/corelib/plugin/qfactoryloader_p.h b/src/corelib/plugin/qfactoryloader_p.h
index c14e5795a8f..d7482b36198 100644
--- a/src/corelib/plugin/qfactoryloader_p.h
+++ b/src/corelib/plugin/qfactoryloader_p.h
@@ -48,6 +48,7 @@ public:
#if QT_CONFIG(library)
~QFactoryLoader();
+ void setLoadHints(QLibrary::LoadHints hints);
void update();
static void refreshAll();
@@ -79,6 +80,7 @@ private:
QString suffix;
QString extraSearchPath;
Qt::CaseSensitivity cs;
+ QLibrary::LoadHints loadHints;
void updateSinglePath(const QString &pluginDir);
#endif
diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp
index e629e2b1f12..f03eba3bffa 100644
--- a/src/corelib/plugin/qlibrary_unix.cpp
+++ b/src/corelib/plugin/qlibrary_unix.cpp
@@ -14,6 +14,11 @@
#ifdef Q_OS_DARWIN
# include <private/qcore_mac_p.h>
+
+// Apple's dyld *does* support RTLD_NODELETE and the library remains loaded in
+// memory after the dlclose() call, but their Objective C crashes when running
+// code from unloaded-but-still-loaded plugins.
+# undef RTLD_NODELETE
#endif
#ifdef Q_OS_ANDROID
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 3409e486ab0..0311b8e3845 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -144,12 +144,12 @@ int pthread_timedjoin_np(...) { return ENOSYS; } // pretend
// Finally, for the thread that called ::exit() (which in most cases happens by
// returning from the main() function), finish() and cleanup() happen at
// function-local static destructor time, and the deref & delete happens later,
-// at global static destruction time. This is important so QLibraryStore can
-// unload plugins between those two steps: it is also destroyed by a global
-// static destructor, but with a lower priority than ours. The order needs to
-// be this way so we delete the event dispatcher before plugins unload, as
-// often the dispatcher for the main thread is provided by a QPA plugin, but
-// the QThreadData object must still be alive when the plugins do unload.
+// at global static destruction time. That way, we delete the event dispatcher
+// before QLibraryStore's clean up runs and unloads remaining plugins. This
+// strategy was chosen because of crashes observed while running the event
+// dispatcher's destructor, and though the cause of the crash was something
+// else (QFactoryLoader always loads with PreventUnloadHint set), other plugins
+// may still attempt to access QThreadData in their global destructors.
Q_CONSTINIT static thread_local QThreadData *currentThreadData = nullptr;