aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2024-02-28 11:53:15 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2024-02-28 11:53:15 +0300
commitfa9dcf5704f1eb4b6632279d80fdd930db73db69 (patch)
treeec1cccaea43a70915c8940678f5a9fe2b37aece9
parent33a9da54e51d674f0dfe00761e89aac4fd4feeb5 (diff)
Fix 'already used by another process' error on deinit
-rw-r--r--bdep/deinit.cxx84
-rw-r--r--bdep/sync.cxx8
-rw-r--r--bdep/sync.hxx10
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 <bdep/sync.hxx>
#include <bdep/fetch.hxx>
+#include <bdep/config.hxx>
using namespace std;
@@ -19,7 +20,9 @@ namespace bdep
cmd_deinit (const cmd_deinit_options& o,
const dir_path& prj,
const shared_ptr<configuration>& c,
- const strings& pkgs)
+ const strings& pkgs,
+ transaction& t,
+ vector<pair<dir_path, string>>& 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<pair<dir_path, string>> 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<configuration>& cfg,
- const strings& pkgs)
+ const strings& pkgs,
+ transaction* origin_tr,
+ vector<pair<dir_path, string>>* 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<configuration>&,
- const strings& pkgs);
+ const strings& pkgs,
+ transaction* = nullptr,
+ vector<pair<dir_path, string>>* created_cfgs = nullptr);
int
cmd_sync (cmd_sync_options&&, cli::group_scanner& args);