aboutsummaryrefslogtreecommitdiff
path: root/build2/operation.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-01-25 15:41:44 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-02-13 12:39:24 +0200
commit88f0780e34116c0441a8d8c58b8a8fd9fde4b1f5 (patch)
tree1240b36211772479dc1220712e0daed4e35ecd85 /build2/operation.cxx
parent61aa8e2b4bd7849838c04dc1f421c4760d88319f (diff)
Add model mutex, make var_pool const by default
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);