Skip to content

Commit

Permalink
Fix tap add/remove race in Supplier
Browse files Browse the repository at this point in the history
This applies a similar fix as was done to Supplier::Preserving in
68d79e7. This may well resolve #2224.
  • Loading branch information
jnthn committed Nov 2, 2018
1 parent 68d79e7 commit 7ee1f3c
Showing 1 changed file with 21 additions and 9 deletions.
30 changes: 21 additions & 9 deletions src/core/Supply.pm6
Expand Up @@ -1537,22 +1537,34 @@ my class Supplier {

method tap(&emit, &done, &quit, &tap) {
my $tle := TapListEntry.new(:&emit, :&done, :&quit);
# Since we run `tap` before adding, there's a small chance of
# a tap removal attempt happening for the add attempt. We use
# these two flags to handle that case. This is safe since we
# only ever access them under lock.
my $added := False;
my $removed := False;
my $t = Tap.new({
$!lock.protect({
my Mu $update := nqp::list();
for nqp::hllize($!tappers) -> \entry {
nqp::push($update, entry) unless entry =:= $tle;
if $added {
my Mu $update := nqp::list();
for nqp::hllize($!tappers) -> \entry {
nqp::push($update, entry) unless entry =:= $tle;
}
$!tappers := $update;
}
$!tappers := $update;
$removed := True;
});
});
tap($t);
$!lock.protect({
my Mu $update := nqp::isconcrete($!tappers)
?? nqp::clone($!tappers)
!! nqp::list();
nqp::push($update, $tle);
$!tappers := $update;
unless $removed {
my Mu $update := nqp::isconcrete($!tappers)
?? nqp::clone($!tappers)
!! nqp::list();
nqp::push($update, $tle);
$!tappers := $update;
}
$added := True;
});
$t
}
Expand Down

0 comments on commit 7ee1f3c

Please sign in to comment.