Skip to content
Permalink
Browse files

Fix tap add/remove race in Supplier

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 7ee1f3c50e955709cc60a5c77cf32290f2eda1e7
Showing with 21 additions and 9 deletions.
  1. +21 −9 src/core/Supply.pm6
@@ -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
}

0 comments on commit 7ee1f3c

Please sign in to comment.
You can’t perform that action at this time.