From fa9dcf5704f1eb4b6632279d80fdd930db73db69 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Wed, 28 Feb 2024 11:53:15 +0300 Subject: Fix 'already used by another process' error on deinit --- bdep/deinit.cxx | 84 +++++++++++++++++++++++++++++++++++++-------------------- bdep/sync.cxx | 8 ++++-- bdep/sync.hxx | 10 ++++++- 3 files changed, 70 insertions(+), 32 deletions(-) diff --git a/bdep/deinit.cxx b/bdep/deinit.cxx index 30152a4..ce1897c 100644 --- a/bdep/deinit.cxx +++ b/bdep/deinit.cxx @@ -10,6 +10,7 @@ #include #include +#include using namespace std; @@ -19,7 +20,9 @@ namespace bdep cmd_deinit (const cmd_deinit_options& o, const dir_path& prj, const shared_ptr& c, - const strings& pkgs) + const strings& pkgs, + transaction& t, + vector>& created_cfgs) { bool force (o.force ()); const dir_path& cfg (c->path); @@ -114,7 +117,7 @@ namespace bdep if (!o.no_fetch ()) cmd_fetch (o, prj, c, true /* fetch_full */); - cmd_sync_deinit (o, prj, c, pkgs); + cmd_sync_deinit (o, prj, c, pkgs, &t, &created_cfgs); } } @@ -231,38 +234,61 @@ namespace bdep continue; } - transaction t (db.begin ()); + vector> created_cfgs; - // Remove collected packages from the configuration. - // - c->packages.erase ( - remove_if (c->packages.begin (), - c->packages.end (), - [&ps] (const package_state& p) - { - return find_if (ps.begin (), - ps.end (), - [&p] (const string& n) - { - return p.name == n; - }) != ps.end (); - }), - c->packages.end ()); - - // If we are deinitializing multiple packages, print their names. - // - if (verb && ps.size () > 1) + try { - for (const string& n: ps) - text << "deinitializing package " << n; + transaction t (db.begin ()); + + // Remove collected packages from the configuration. + // + c->packages.erase ( + remove_if (c->packages.begin (), + c->packages.end (), + [&ps] (const package_state& p) + { + return find_if (ps.begin (), + ps.end (), + [&p] (const string& n) + { + return p.name == n; + }) != ps.end (); + }), + c->packages.end ()); + + // If we are deinitializing multiple packages, print their names. + // + if (verb && ps.size () > 1) + { + for (const string& n: ps) + text << "deinitializing package " << n; + } + + // The same story as in init with regard to the state update order. + // + cmd_deinit (o, prj, c, ps, t, created_cfgs); + + db.update (c); + t.commit (); } + catch (const failed&) + { + if (!created_cfgs.empty ()) + { + transaction t (db.begin ()); - // The same story as in init with regard to the state update order. - // - cmd_deinit (o, prj, c, ps); + for (const auto& c: created_cfgs) + cmd_config_add (prj, + t, + c.first /* path */, + c.second /* name */, + c.second /* type */); - db.update (c); - t.commit (); + t.commit (); + } + + throw; + } // Remove our repository from the configuration if we have no more // packages that are initialized in it. diff --git a/bdep/sync.cxx b/bdep/sync.cxx index 77135fd..295b46f 100644 --- a/bdep/sync.cxx +++ b/bdep/sync.cxx @@ -2385,7 +2385,9 @@ namespace bdep cmd_sync_deinit (const common_options& co, const dir_path& prj, const shared_ptr& cfg, - const strings& pkgs) + const strings& pkgs, + transaction* origin_tr, + vector>* created_cfgs) { sync_configs ocfgs {cfg}; linked_configs lcfgs (find_config_cluster (co, cfg->path)); @@ -2407,7 +2409,9 @@ namespace bdep pkgs, sys_options (), false /* create_host_config */, - false /* create_build2_config */); + false /* create_build2_config */, + origin_tr, + created_cfgs); } int diff --git a/bdep/sync.hxx b/bdep/sync.hxx index f951a40..f71fd12 100644 --- a/bdep/sync.hxx +++ b/bdep/sync.hxx @@ -155,11 +155,19 @@ namespace bdep // specified configuration with their project directory repository being // masked. // + // Note that it is not very likely but still possible that the + // deinitialization of a package may end up with associating new + // configurations with the project. Think of deorphaning a package, which + // has been replaced with another version that got some new build-time + // dependency. + // void cmd_sync_deinit (const common_options&, const dir_path& prj, const shared_ptr&, - const strings& pkgs); + const strings& pkgs, + transaction* = nullptr, + vector>* created_cfgs = nullptr); int cmd_sync (cmd_sync_options&&, cli::group_scanner& args); -- cgit v1.1