aboutsummaryrefslogtreecommitdiff
path: root/build2/operation.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'build2/operation.cxx')
-rw-r--r--build2/operation.cxx50
1 files changed, 39 insertions, 11 deletions
diff --git a/build2/operation.cxx b/build2/operation.cxx
index 545bc9e..3871970 100644
--- a/build2/operation.cxx
+++ b/build2/operation.cxx
@@ -44,8 +44,9 @@ namespace build2
// perform
//
void
- load (const path& bf,
+ load (ulock&,
scope& root,
+ const path& bf,
const dir_path& out_base,
const dir_path& src_base,
const location&)
@@ -62,11 +63,12 @@ namespace build2
// Load the buildfile unless it has already been loaded.
//
- source_once (bf, root, base, root);
+ source_once (root, base, bf, root);
}
void
- search (scope&,
+ search (ulock&,
+ scope&,
const target_key& tk,
const location& l,
action_targets& ts)
@@ -81,26 +83,38 @@ namespace build2
}
void
- match (action a, action_targets& ts)
+ match (ulock& ml, action a, action_targets& ts)
{
tracer trace ("match");
if (verb >= 6)
dump (a);
- for (void* vt: ts)
+ // Relock for shared access.
+ //
+ ml.unlock ();
+
{
- target& t (*static_cast<target*> (vt));
- l5 ([&]{trace << "matching " << t;});
- match (a, t);
+ for (void* vt: ts)
+ {
+ target& t (*static_cast<target*> (vt));
+ l5 ([&]{trace << "matching " << t;});
+
+ slock sl (*ml.mutex ());
+ model_lock = &sl; // @@ Guard?
+ match (sl, a, t);
+ model_lock = nullptr;
+ }
}
+ ml.lock ();
+
if (verb >= 6)
dump (a);
}
void
- execute (action a, const action_targets& ts, bool quiet)
+ execute (ulock& ml, action a, const action_targets& ts, bool quiet)
{
tracer trace ("execute");
@@ -109,13 +123,21 @@ namespace build2
//
vector<reference_wrapper<target>> psp;
- auto body = [a, quiet, &psp, &trace] (void* v)
+ auto body = [&ml, a, quiet, &psp, &trace] (void* v)
{
target& t (*static_cast<target*> (v));
l5 ([&]{trace << diag_doing (a, t);});
- switch (execute (a, t))
+ target_state ts;
+ {
+ slock sl (*ml.mutex ());
+ model_lock = &sl; // @@ Guard?
+ ts = execute (a, t);
+ model_lock = nullptr;
+ }
+
+ switch (ts)
{
case target_state::unchanged:
{
@@ -135,11 +157,17 @@ namespace build2
}
};
+ // Relock for shared access.
+ //
+ ml.unlock ();
+
if (current_mode == execution_mode::first)
for (void* v: ts) body (v);
else
for (void* v: reverse_iterate (ts)) body (v);
+ ml.lock ();
+
// We should have executed every target that we matched.
//
assert (dependency_count == 0);