diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2020-03-20 05:47:12 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2020-03-20 05:47:12 +0200 |
commit | a9bfeabe70a05b4e0776d31a4ae62983bb9fc6e3 (patch) | |
tree | ca8627fd5ee313bb120fde10c53665debaba5be5 | |
parent | a00647acd3b1c08c61234af994c2c29735a9b3ce (diff) |
Tighten add_adhoc_member() against races
-rw-r--r-- | libbuild2/algorithm.cxx | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx index 34283f9..7788b90 100644 --- a/libbuild2/algorithm.cxx +++ b/libbuild2/algorithm.cxx @@ -278,20 +278,23 @@ namespace build2 const_ptr<target>* mp (&t.member); for (; *mp != nullptr && !(*mp)->is_a (tt); mp = &(*mp)->member) ; - target& m (*mp != nullptr // Might already be there. - ? **mp - : t.ctx.targets.insert (tt, - dir, - out, - move (n), - nullopt /* ext */, - true /* implied */, - trace).first); - if (*mp == nullptr) - { - *mp = &m; - m.group = &t; - } + if (*mp != nullptr) // Might already be there. + return **mp; + + pair<target&, ulock> r ( + t.ctx.targets.insert_locked (tt, + dir, + out, + move (n), + nullopt /* ext */, + true /* implied */, + trace)); + + assert (r.second.owns_lock ()); + + target& m (r.first); + *mp = &m; + m.group = &t; return m; }; |