QLibrary: make isLoaded() report whether this object has load()ed

This reverts commit c2a92199b57b195176d2a0d68d140d72c1cbfb71
"QLibrary::setFileNameAndVersion: reset the tag after findOrCreate".
This restores the behavior of resolve() and compatibility with Qt 4 and
5, which is documented to imply a call to load().

Do note that if you call load() or resolve() and don't call unload(),
the library you've loaded can never be unloaded now. So don't leak!

[ChangeLog][Important Behavior Changes] QLibrary::isLoaded() now reports
whether this instance of QLibrary has succeeded in loading the library,
via direct or indirect call to load(). Previously, it used to reported
whether the actual library was loaded by any QLibrary instance.

The change to QLibrary::resolve() itself is effectively a no-op in this
patch, because isLoaded() would have returned false, but it ensures that
the implementation does what it says it will do.

Fixes: QTBUG-114977
Change-Id: I907aa7aea8ef48469498fffd176d7a76ae73e04a
Reviewed-by: Ievgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit 1ca71cbff0fe28185b4854a162f924af700d57e0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Thiago Macieira 2023-06-30 08:48:05 -07:00 committed by Qt Cherry-pick Bot
parent 66044f94cb
commit a83d59b901
2 changed files with 27 additions and 24 deletions

View File

@ -834,13 +834,17 @@ bool QLibrary::unload()
}
/*!
Returns \c true if the library is loaded; otherwise returns \c false.
Returns \c true if load() succeeded; otherwise returns \c false.
\note Prior to Qt 6.6, this function would return \c true even without a
call to load() if another QLibrary object on the same library had caused it
to be loaded.
\sa load()
*/
bool QLibrary::isLoaded() const
{
return d && d->pHnd.loadRelaxed();
return d.tag() == Loaded;
}
@ -977,8 +981,7 @@ void QLibrary::setFileNameAndVersion(const QString &fileName, const QString &ver
d->release();
}
QLibraryPrivate *dd = QLibraryPrivate::findOrCreate(fileName, version, lh);
d = dd;
d.setTag(isLoaded() ? Loaded : NotLoaded);
d = QTaggedPointer(dd, NotLoaded); // we haven't load()ed
}
/*!

View File

@ -256,10 +256,10 @@ void tst_QLibrary::setFileNameAndVersionTwice()
QVERIFY(!library.isLoaded());
// set back
// it'll look like it isn't loaded, but it is and we can't unload it!
library.setFileNameAndVersion(directory + "/mylib", 1);
QVERIFY(library.isLoaded());
QVERIFY(library.unload());
QVERIFY(!library.isLoaded());
QVERIFY(!library.unload());
}
void tst_QLibrary::load_data()
@ -433,11 +433,22 @@ void tst_QLibrary::resolve()
QFETCH( bool, goodPointer );
QLibrary library(lib);
QVERIFY(!library.isLoaded());
testFunc func = (testFunc) library.resolve(symbol.toLatin1());
if (goodPointer) {
QVERIFY( func != 0 );
QVERIFY(library.isLoaded());
QVERIFY(func);
QLibrary lib2(lib);
QVERIFY(!lib2.isLoaded());
QVERIFY(lib2.load());
// this unload() won't unload and it must still be loaded
QVERIFY(!lib2.unload());
func(); // doesn't crash
} else {
QVERIFY( func == 0 );
QVERIFY(func == nullptr);
}
library.unload();
}
@ -647,7 +658,7 @@ void tst_QLibrary::multipleInstancesForOneLibrary()
QCOMPARE(lib2.isLoaded(), false);
lib1.load();
QCOMPARE(lib1.isLoaded(), true);
QCOMPARE(lib2.isLoaded(), true);
QCOMPARE(lib2.isLoaded(), false); // lib2 didn't call load()
QCOMPARE(lib1.unload(), true);
QCOMPARE(lib1.isLoaded(), false);
QCOMPARE(lib2.isLoaded(), false);
@ -656,7 +667,7 @@ void tst_QLibrary::multipleInstancesForOneLibrary()
QCOMPARE(lib1.isLoaded(), true);
QCOMPARE(lib2.isLoaded(), true);
QCOMPARE(lib1.unload(), false);
QCOMPARE(lib1.isLoaded(), true);
QCOMPARE(lib1.isLoaded(), false); // lib1 did call unload()
QCOMPARE(lib2.isLoaded(), true);
QCOMPARE(lib2.unload(), true);
QCOMPARE(lib1.isLoaded(), false);
@ -665,17 +676,6 @@ void tst_QLibrary::multipleInstancesForOneLibrary()
// Finally; unload on that is already unloaded
QCOMPARE(lib1.unload(), false);
}
//now let's try with a 3rd one that will go out of scope
{
QLibrary lib1(lib);
QCOMPARE(lib1.isLoaded(), false);
lib1.load();
QCOMPARE(lib1.isLoaded(), true);
}
QLibrary lib2(lib);
//lib2 should be loaded because lib1 was loaded and never unloaded
QCOMPARE(lib2.isLoaded(), true);
}
QTEST_MAIN(tst_QLibrary)