Avoid package object being reused after 3d7310af3

This commit is contained in:
Martchus 2022-02-20 19:50:44 +01:00
parent d11ba43bf0
commit bdbfd42e5e
7 changed files with 59 additions and 44 deletions

View File

@ -241,9 +241,9 @@ std::vector<PackageSearchResult> Config::findPackages(
if (!databasePred(db)) {
continue;
}
db.allPackages([&](StorageID packageID, const std::shared_ptr<Package> &package) {
db.allPackages([&](StorageID packageID, std::shared_ptr<Package> &&package) {
if (packagePred(db, *package)) {
pkgs.emplace_back(db, package, packageID);
pkgs.emplace_back(db, std::move(package), packageID);
}
return false;
});
@ -258,9 +258,9 @@ std::vector<PackageSearchResult> Config::findPackages(const std::function<bool(c
{
auto pkgs = std::vector<PackageSearchResult>();
for (auto &db : databases) {
db.allPackages([&](StorageID packageID, const std::shared_ptr<Package> &package) {
db.allPackages([&](StorageID packageID, std::shared_ptr<Package> &&package) {
if (pred(db, *package)) {
pkgs.emplace_back(db, package, packageID);
pkgs.emplace_back(db, std::move(package), packageID);
}
return false;
});

View File

@ -246,7 +246,7 @@ void Database::addPackageDependencies(StorageID packageID, const std::shared_ptr
}
}
void Database::allPackages(const PackageVisitor &visitor)
void Database::allPackages(const PackageVisitorMove &visitor)
{
auto txn = m_storage->packages.getROTransaction();
for (auto i = txn.begin<std::shared_ptr>(); i != txn.end(); ++i) {
@ -272,7 +272,7 @@ std::size_t Database::packageCount() const
return m_storage->packages.getROTransaction().size();
}
void Database::providingPackages(const Dependency &dependency, bool reverse, const PackageVisitor &visitor)
void Database::providingPackages(const Dependency &dependency, bool reverse, const PackageVisitorConst &visitor)
{
auto providesTxn = (reverse ? m_storage->requiredDeps : m_storage->providedDeps).getROTransaction();
auto packagesTxn = m_storage->packages.getROTransaction();
@ -283,7 +283,7 @@ void Database::providingPackages(const Dependency &dependency, bool reverse, con
continue;
}
for (const auto packageID : providedDependency.relevantPackages) {
const auto res = m_storage->packageCache.retrieve(*m_storage, &packagesTxn, packageID);
auto res = m_storage->packageCache.retrieve(*m_storage, &packagesTxn, packageID);
if (res.pkg && visitor(packageID, res.pkg)) {
return;
}
@ -291,13 +291,13 @@ void Database::providingPackages(const Dependency &dependency, bool reverse, con
}
}
void Database::providingPackages(const std::string &libraryName, bool reverse, const PackageVisitor &visitor)
void Database::providingPackages(const std::string &libraryName, bool reverse, const PackageVisitorConst &visitor)
{
auto providesTxn = (reverse ? m_storage->requiredLibs : m_storage->providedLibs).getROTransaction();
auto packagesTxn = m_storage->packages.getROTransaction();
for (auto [i, end] = providesTxn.equal_range<0>(libraryName); i != end; ++i) {
for (const auto packageID : i->relevantPackages) {
const auto res = m_storage->packageCache.retrieve(*m_storage, &packagesTxn, packageID);
auto res = m_storage->packageCache.retrieve(*m_storage, &packagesTxn, packageID);
if (res.pkg && visitor(packageID, res.pkg)) {
return;
}
@ -502,8 +502,9 @@ std::unordered_map<PackageSpec, UnresolvedDependencies> Database::detectUnresolv
LibPkg::PackageUpdates LibPkg::Database::checkForUpdates(const std::vector<LibPkg::Database *> &updateSources, UpdateCheckOptions options)
{
auto results = PackageUpdates();
allPackages([&](StorageID myPackageID, const std::shared_ptr<Package> &package) {
allPackages([&](StorageID myPackageID, std::shared_ptr<Package> &&package) {
auto regularName = std::string();
auto used = false;
if (options & UpdateCheckOptions::ConsiderRegularPackage) {
const auto decomposedName = package->decomposeName();
if ((!decomposedName.targetPrefix.empty() || !decomposedName.vcsSuffix.empty()) && !decomposedName.isVcsPackage()) {
@ -534,37 +535,42 @@ LibPkg::PackageUpdates LibPkg::Database::checkForUpdates(const std::vector<LibPk
if (list) {
list->emplace_back(
PackageSearchResult(*this, package, myPackageID), PackageSearchResult(*updateSource, updatePackage, updatePackageID));
used = true;
}
}
if (!foundPackage) {
results.orphans.emplace_back(PackageSearchResult(*this, package, myPackageID));
used = true;
}
if (regularName.empty()) {
return false;
if (!regularName.empty()) {
for (auto *const updateSource : updateSources) {
const auto [updatePackageID, updatePackage] = updateSource->findPackageWithID(regularName);
if (!updatePackage) {
continue;
}
const auto versionDiff = package->compareVersion(*updatePackage);
std::vector<PackageUpdate> *list = nullptr;
switch (versionDiff) {
case PackageVersionComparison::SoftwareUpgrade:
list = &results.versionUpdates;
break;
case PackageVersionComparison::PackageUpgradeOnly:
list = &results.packageUpdates;
break;
case PackageVersionComparison::NewerThanSyncVersion:
list = &results.downgrades;
break;
default:;
}
if (list) {
list->emplace_back(
PackageSearchResult(*this, package, myPackageID), PackageSearchResult(*updateSource, updatePackage, updatePackageID));
used = true;
}
}
}
for (auto *const updateSource : updateSources) {
const auto [updatePackageID, updatePackage] = updateSource->findPackageWithID(regularName);
if (!updatePackage) {
continue;
}
const auto versionDiff = package->compareVersion(*updatePackage);
std::vector<PackageUpdate> *list = nullptr;
switch (versionDiff) {
case PackageVersionComparison::SoftwareUpgrade:
list = &results.versionUpdates;
break;
case PackageVersionComparison::PackageUpgradeOnly:
list = &results.packageUpdates;
break;
case PackageVersionComparison::NewerThanSyncVersion:
list = &results.downgrades;
break;
default:;
}
if (list) {
list->emplace_back(
PackageSearchResult(*this, package, myPackageID), PackageSearchResult(*updateSource, updatePackage, updatePackageID));
}
if (used) {
package.reset();
}
return false;
});

View File

@ -27,6 +27,7 @@ struct LIBPKG_EXPORT DatabaseInfo {
struct LIBPKG_EXPORT PackageSearchResult {
PackageSearchResult();
PackageSearchResult(Database &database, const std::shared_ptr<Package> &package, StorageID id);
PackageSearchResult(Database &database, std::shared_ptr<Package> &&package, StorageID id);
PackageSearchResult(Database &database, Package &&package, StorageID id);
bool operator==(const PackageSearchResult &other) const;
@ -112,7 +113,8 @@ private:
};
struct LIBPKG_EXPORT Database : public ReflectiveRapidJSON::JsonSerializable<Database>, public ReflectiveRapidJSON::BinarySerializable<Database> {
using PackageVisitor = std::function<bool(StorageID, const std::shared_ptr<Package> &)>;
using PackageVisitorMove = std::function<bool(StorageID, std::shared_ptr<Package> &&)>; // package is invalidated/reused unless moved from!!!
using PackageVisitorConst = std::function<bool(StorageID, const std::shared_ptr<Package> &)>;
using PackageVisitorByName = std::function<bool(std::string_view, const std::function<PackageSpec(void)> &)>;
friend struct PackageUpdater;
@ -134,11 +136,11 @@ struct LIBPKG_EXPORT Database : public ReflectiveRapidJSON::JsonSerializable<Dat
std::vector<std::shared_ptr<Package>> findPackages(const std::function<bool(const Database &, const Package &)> &pred);
void removePackageDependencies(StorageID packageID, const std::shared_ptr<Package> &package);
void addPackageDependencies(StorageID packageID, const std::shared_ptr<Package> &package);
void allPackages(const PackageVisitor &visitor);
void allPackages(const PackageVisitorMove &visitor);
void allPackagesByName(const PackageVisitorByName &visitor);
std::size_t packageCount() const;
void providingPackages(const Dependency &dependency, bool reverse, const PackageVisitor &visitor);
void providingPackages(const std::string &libraryName, bool reverse, const PackageVisitor &visitor);
void providingPackages(const Dependency &dependency, bool reverse, const PackageVisitorConst &visitor);
void providingPackages(const std::string &libraryName, bool reverse, const PackageVisitorConst &visitor);
bool provides(const Dependency &dependency, bool reverse = false) const;
bool provides(const std::string &libraryName, bool reverse = false) const;
std::shared_ptr<Package> findPackage(StorageID packageID);
@ -187,6 +189,13 @@ inline PackageSearchResult::PackageSearchResult(Database &database, const std::s
{
}
inline PackageSearchResult::PackageSearchResult(Database &database, std::shared_ptr<Package> &&package, StorageID id)
: db(&database)
, pkg(std::move(package))
, id(id)
{
}
inline PackageSearchResult::PackageSearchResult(Database &database, Package &&package, StorageID id)
: db(&database)
, pkg(std::make_shared<Package>(std::move(package)))

View File

@ -451,7 +451,7 @@ void CheckForProblems::run()
problems.emplace_back(
RepositoryProblem{ .desc = "configured local package directory \"" % db->localPkgDir + "\" is not a directory" });
}
db->allPackages([&](LibPkg::StorageID, const std::shared_ptr<LibPkg::Package> &package) {
db->allPackages([&](LibPkg::StorageID, std::shared_ptr<LibPkg::Package> &&package) {
if (!package->packageInfo) {
problems.emplace_back(RepositoryProblem{ .desc = "no package info present", .pkg = package->name });
return false;

View File

@ -153,7 +153,7 @@ void BuildActionsTests::logTestSetup()
{
for (auto &db : m_setup.config.databases) {
cout << EscapeCodes::Phrases::Info << "Packages of " << db.name << ':' << EscapeCodes::Phrases::End;
db.allPackages([](LibPkg::StorageID, const std::shared_ptr<LibPkg::Package> &package) {
db.allPackages([](LibPkg::StorageID, std::shared_ptr<LibPkg::Package> &&package) {
cout << " - " << package->name << '\n';
return false;
});

View File

@ -169,9 +169,9 @@ std::shared_ptr<AurQuerySession> queryAurPackagesForDatabase(LogContext &log, Se
configReadLock = &ownConfigReadLock;
}
auto &aurDb = setup.config.aur;
database.allPackages([&aurDb, &missingPackages](StorageID, const std::shared_ptr<Package> &package) {
database.allPackages([&aurDb, &missingPackages](StorageID, std::shared_ptr<Package> &&package) {
if (const auto aurPackage = aurDb.findPackage(package->name); !aurPackage) {
missingPackages.emplace_back(package->name);
missingPackages.emplace_back(std::move(package->name));
}
return false;
});

View File

@ -131,7 +131,7 @@ int main(int argc, const char *argv[])
}
}
for (auto &db : cfg.databases) {
db.allPackages([&](LibPkg::StorageID, const std::shared_ptr<LibPkg::Package> &package) {
db.allPackages([&](LibPkg::StorageID, std::shared_ptr<LibPkg::Package> &&package) {
const auto &pkgInfo = package->packageInfo;
if (!pkgInfo) {
return false;