aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2022-09-19 14:17:10 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2022-09-19 14:17:10 +0200
commit58e495733d402bb4e97238ae6c8e8344eb4b2161 (patch)
tree914e20c16f349ab4d41b78d8f55e43ef0735f171
parent47ae21f6558f81ae7c13d143d297f61acae2b530 (diff)
Add target_lock::first to distinguish first lock of target
-rw-r--r--libbuild2/algorithm.cxx16
-rw-r--r--libbuild2/algorithm.hxx4
-rw-r--r--libbuild2/algorithm.ixx6
3 files changed, 15 insertions, 11 deletions
diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx
index 76f7c4c..696a09d 100644
--- a/libbuild2/algorithm.cxx
+++ b/libbuild2/algorithm.cxx
@@ -256,7 +256,7 @@ namespace build2
fail << "dependency cycle detected involving target " << ct;
if (!wq)
- return target_lock {a, nullptr, e - b};
+ return target_lock {a, nullptr, e - b, false};
// We also unlock the phase for the duration of the wait. Why?
// Consider this scenario: we are trying to match a dir{} target whose
@@ -272,7 +272,7 @@ namespace build2
// We don't lock already applied or executed targets.
//
if (e >= appl)
- return target_lock {a, nullptr, e - b};
+ return target_lock {a, nullptr, e - b, false};
}
// We now have the lock. Analyze the old value and decide what to do.
@@ -281,7 +281,8 @@ namespace build2
target::opstate& s (t[a]);
size_t offset;
- if (e <= b)
+ bool first;
+ if ((first = (e <= b)))
{
// First lock for this operation.
//
@@ -298,7 +299,7 @@ namespace build2
offset == target::offset_matched);
}
- return target_lock {a, &t, offset};
+ return target_lock {a, &t, offset, first};
}
void
@@ -991,7 +992,7 @@ namespace build2
*task_count,
[a, try_match] (const diag_frame* ds,
const target_lock* ls,
- target& t, size_t offset)
+ target& t, size_t offset, bool first)
{
// Switch to caller's diag and lock stacks.
//
@@ -1002,7 +1003,7 @@ namespace build2
{
phase_lock pl (t.ctx, run_phase::match); // Throws.
{
- target_lock l {a, &t, offset}; // Reassemble.
+ target_lock l {a, &t, offset, first}; // Reassemble.
match_impl (l, false /* step */, try_match);
// Unlock within the match phase.
}
@@ -1012,7 +1013,8 @@ namespace build2
diag_frame::stack (),
target_lock::stack (),
ref (*ld.target),
- ld.offset))
+ ld.offset,
+ ld.first))
return make_pair (true, target_state::postponed); // Queued.
// Matched synchronously, fall through.
diff --git a/libbuild2/algorithm.hxx b/libbuild2/algorithm.hxx
index b7f6809..e558d3a 100644
--- a/libbuild2/algorithm.hxx
+++ b/libbuild2/algorithm.hxx
@@ -191,6 +191,7 @@ namespace build2
action_type action;
target_type* target = nullptr;
size_t offset = 0;
+ bool first;
explicit operator bool () const {return target != nullptr;}
@@ -209,13 +210,14 @@ namespace build2
// Implementation details.
//
~target_lock ();
- target_lock (action_type, target_type*, size_t);
+ target_lock (action_type, target_type*, size_t, bool);
struct data
{
action_type action;
target_type* target;
size_t offset;
+ bool first;
};
data
diff --git a/libbuild2/algorithm.ixx b/libbuild2/algorithm.ixx
index 8fc5390..417a10e 100644
--- a/libbuild2/algorithm.ixx
+++ b/libbuild2/algorithm.ixx
@@ -220,8 +220,8 @@ namespace build2
unlock_impl (action, target&, size_t);
inline target_lock::
- target_lock (action_type a, target_type* t, size_t o)
- : action (a), target (t), offset (o)
+ target_lock (action_type a, target_type* t, size_t o, bool f)
+ : action (a), target (t), offset (o), first (f)
{
if (target != nullptr)
prev = stack (this);
@@ -260,7 +260,7 @@ namespace build2
inline auto target_lock::
release () -> data
{
- data r {action, target, offset};
+ data r {action, target, offset, first};
if (target != nullptr)
{