Move most of the QLibraryPrivate initialization to its constructor
This commit moves the setting of the loadHints to inside the constructor or to QLibraryStore::findOrCreate (which is under a mutex). This avoids data race conditions with two threads asking for the same plugin at the same time, with different load hints. This also opportunistically moves the setting of the error message for empty file names. Task-number: QTBUG-39642 Change-Id: I497a41781d10e407d6420116a0b05fdfe2b548de Reviewed-by: David Faure <david.faure@kdab.com>bb10
parent
6b15a5a869
commit
4a83ce611d
|
|
@ -359,7 +359,7 @@ class QLibraryStore
|
|||
{
|
||||
public:
|
||||
inline ~QLibraryStore();
|
||||
static inline QLibraryPrivate *findOrCreate(const QString &fileName, const QString &version);
|
||||
static inline QLibraryPrivate *findOrCreate(const QString &fileName, const QString &version, QLibrary::LoadHints loadHints);
|
||||
static inline void releaseLibrary(QLibraryPrivate *lib);
|
||||
|
||||
static inline void cleanup();
|
||||
|
|
@ -438,17 +438,21 @@ QLibraryStore *QLibraryStore::instance()
|
|||
return qt_library_data;
|
||||
}
|
||||
|
||||
inline QLibraryPrivate *QLibraryStore::findOrCreate(const QString &fileName, const QString &version)
|
||||
inline QLibraryPrivate *QLibraryStore::findOrCreate(const QString &fileName, const QString &version,
|
||||
QLibrary::LoadHints loadHints)
|
||||
{
|
||||
QMutexLocker locker(&qt_library_mutex);
|
||||
QLibraryStore *data = instance();
|
||||
|
||||
// check if this library is already loaded
|
||||
QLibraryPrivate *lib = 0;
|
||||
if (Q_LIKELY(data))
|
||||
if (Q_LIKELY(data)) {
|
||||
lib = data->libraryMap.value(fileName);
|
||||
if (lib)
|
||||
lib->mergeLoadHints(loadHints);
|
||||
}
|
||||
if (!lib)
|
||||
lib = new QLibraryPrivate(fileName, version);
|
||||
lib = new QLibraryPrivate(fileName, version, loadHints);
|
||||
|
||||
// track this library
|
||||
if (Q_LIKELY(data))
|
||||
|
|
@ -479,21 +483,34 @@ inline void QLibraryStore::releaseLibrary(QLibraryPrivate *lib)
|
|||
delete lib;
|
||||
}
|
||||
|
||||
QLibraryPrivate::QLibraryPrivate(const QString &canonicalFileName, const QString &version)
|
||||
QLibraryPrivate::QLibraryPrivate(const QString &canonicalFileName, const QString &version, QLibrary::LoadHints loadHints)
|
||||
: pHnd(0), fileName(canonicalFileName), fullVersion(version), instance(0),
|
||||
loadHints(0),
|
||||
loadHints(loadHints),
|
||||
libraryRefCount(0), libraryUnloadCount(0), pluginState(MightBeAPlugin)
|
||||
{ }
|
||||
|
||||
QLibraryPrivate *QLibraryPrivate::findOrCreate(const QString &fileName, const QString &version)
|
||||
{
|
||||
return QLibraryStore::findOrCreate(fileName, version);
|
||||
if (canonicalFileName.isEmpty())
|
||||
errorString = QLibrary::tr("The shared library was not found.");
|
||||
}
|
||||
|
||||
QLibraryPrivate *QLibraryPrivate::findOrCreate(const QString &fileName, const QString &version,
|
||||
QLibrary::LoadHints loadHints)
|
||||
{
|
||||
return QLibraryStore::findOrCreate(fileName, version, loadHints);
|
||||
}
|
||||
|
||||
QLibraryPrivate::~QLibraryPrivate()
|
||||
{
|
||||
}
|
||||
|
||||
void QLibraryPrivate::mergeLoadHints(QLibrary::LoadHints lh)
|
||||
{
|
||||
// if the library is already loaded, we can't change the load hints
|
||||
if (pHnd)
|
||||
return;
|
||||
|
||||
loadHints = lh;
|
||||
}
|
||||
|
||||
QFunctionPointer QLibraryPrivate::resolve(const char *symbol)
|
||||
{
|
||||
if (!pHnd)
|
||||
|
|
|
|||
|
|
@ -94,7 +94,8 @@ public:
|
|||
void release();
|
||||
QFunctionPointer resolve(const char *);
|
||||
|
||||
static QLibraryPrivate *findOrCreate(const QString &fileName, const QString &version = QString());
|
||||
static QLibraryPrivate *findOrCreate(const QString &fileName, const QString &version = QString(),
|
||||
QLibrary::LoadHints loadHints = 0);
|
||||
static QStringList suffixes_sys(const QString &fullVersion);
|
||||
static QStringList prefixes_sys();
|
||||
|
||||
|
|
@ -117,8 +118,9 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
explicit QLibraryPrivate(const QString &canonicalFileName, const QString &version);
|
||||
explicit QLibraryPrivate(const QString &canonicalFileName, const QString &version, QLibrary::LoadHints loadHints);
|
||||
~QLibraryPrivate();
|
||||
void mergeLoadHints(QLibrary::LoadHints loadHints);
|
||||
|
||||
bool load_sys();
|
||||
bool unload_sys();
|
||||
|
|
|
|||
|
|
@ -352,11 +352,8 @@ void QPluginLoader::setFileName(const QString &fileName)
|
|||
else
|
||||
fn = locatePlugin(fileName);
|
||||
|
||||
d = QLibraryPrivate::findOrCreate(fn);
|
||||
d->loadHints = lh;
|
||||
if (fn.isEmpty())
|
||||
d->errorString = QLibrary::tr("The shared library was not found.");
|
||||
else
|
||||
d = QLibraryPrivate::findOrCreate(fn, QString(), lh);
|
||||
if (!fn.isEmpty())
|
||||
d->updatePluginState();
|
||||
|
||||
#else
|
||||
|
|
|
|||
Loading…
Reference in New Issue