Skip to content

Commit

Permalink
Enqueue senders in Channel#close (#5880)
Browse files Browse the repository at this point in the history
Fixes #5875
  • Loading branch information
carlhoerberg authored and RX14 committed Mar 30, 2018
1 parent 0424b22 commit f33a910
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
23 changes: 23 additions & 0 deletions spec/std/channel_spec.cr
Expand Up @@ -137,6 +137,29 @@ describe Channel::Unbuffered do
spawn { ch.send 123 }
ch.receive?.should eq(123)
end

it "wakes up the sender fiber when channel is closed" do
ch = Channel::Unbuffered(Nil).new
sender_closed = false
spawn do
ch.send nil
ch.send nil
rescue Channel::ClosedError
sender_closed = true
end
receiver_closed = false
spawn do
Fiber.yield
ch.receive
rescue Channel::ClosedError
receiver_closed = true
end
Fiber.yield
ch.close
Fiber.yield
sender_closed.should be_true
receiver_closed.should be_true
end
end

describe Channel::Buffered do
Expand Down
11 changes: 11 additions & 0 deletions src/concurrent/channel.cr
Expand Up @@ -30,6 +30,8 @@ abstract class Channel(T)

def close
@closed = true
Scheduler.enqueue @senders
@senders.clear
Scheduler.enqueue @receivers
@receivers.clear
nil
Expand Down Expand Up @@ -259,6 +261,7 @@ class Channel::Unbuffered(T) < Channel(T)
@value.tap do
@has_value = false
Scheduler.enqueue @sender.not_nil!
@sender = nil
end
end

Expand All @@ -269,4 +272,12 @@ class Channel::Unbuffered(T) < Channel(T)
def full?
@has_value || @receivers.empty?
end

def close
super
if sender = @sender
Scheduler.enqueue sender
@sender = nil
end
end
end

0 comments on commit f33a910

Please sign in to comment.