diff options
Diffstat (limited to 'libbuild2/algorithm.cxx')
-rw-r--r-- | libbuild2/algorithm.cxx | 68 |
1 files changed, 67 insertions, 1 deletions
diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx index ded34b4..2f59c73 100644 --- a/libbuild2/algorithm.cxx +++ b/libbuild2/algorithm.cxx @@ -20,6 +20,37 @@ using namespace butl; namespace build2 { const target& + search (const target& t, const prerequisite& p) + { + assert (phase == run_phase::match); + + const target* r (p.target.load (memory_order_consume)); + + if (r == nullptr) + r = &search_custom (p, search (t, p.key ())); + + return *r; + } + + const target* + search_existing (const prerequisite& p) + { + assert (phase == run_phase::match || phase == run_phase::execute); + + const target* r (p.target.load (memory_order_consume)); + + if (r == nullptr) + { + r = search_existing (p.key ()); + + if (r != nullptr) + search_custom (p, *r); + } + + return r; + } + + const target& search (const target& t, const prerequisite_key& pk) { assert (phase == run_phase::match); @@ -637,7 +668,7 @@ namespace build2 return ct.try_matched_state (a, false); } - group_view + static group_view resolve_members_impl (action a, const target& g, target_lock l) { // Note that we will be unlocked if the target is already applied. @@ -709,6 +740,41 @@ namespace build2 return r; } + group_view + resolve_members (action a, const target& g) + { + group_view r; + + if (a.outer ()) + a = a.inner_action (); + + // We can be called during execute though everything should have been + // already resolved. + // + switch (phase) + { + case run_phase::match: + { + // Grab a target lock to make sure the group state is synchronized. + // + target_lock l (lock_impl (a, g, scheduler::work_none)); + r = g.group_members (a); + + // If the group members are alrealy known or there is nothing else + // we can do, then unlock and return. + // + if (r.members == nullptr && l.offset != target::offset_executed) + r = resolve_members_impl (a, g, move (l)); + + break; + } + case run_phase::execute: r = g.group_members (a); break; + case run_phase::load: assert (false); + } + + return r; + } + void resolve_group_impl (action, const target&, target_lock l) { |