Skip to content

Commit f33a910

Browse files
carlhoerbergRX14
authored andcommitted
Enqueue senders in Channel#close (#5880)
Fixes #5875
1 parent 0424b22 commit f33a910

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

spec/std/channel_spec.cr

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,29 @@ describe Channel::Unbuffered do
137137
spawn { ch.send 123 }
138138
ch.receive?.should eq(123)
139139
end
140+
141+
it "wakes up the sender fiber when channel is closed" do
142+
ch = Channel::Unbuffered(Nil).new
143+
sender_closed = false
144+
spawn do
145+
ch.send nil
146+
ch.send nil
147+
rescue Channel::ClosedError
148+
sender_closed = true
149+
end
150+
receiver_closed = false
151+
spawn do
152+
Fiber.yield
153+
ch.receive
154+
rescue Channel::ClosedError
155+
receiver_closed = true
156+
end
157+
Fiber.yield
158+
ch.close
159+
Fiber.yield
160+
sender_closed.should be_true
161+
receiver_closed.should be_true
162+
end
140163
end
141164

142165
describe Channel::Buffered do

src/concurrent/channel.cr

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ abstract class Channel(T)
3030

3131
def close
3232
@closed = true
33+
Scheduler.enqueue @senders
34+
@senders.clear
3335
Scheduler.enqueue @receivers
3436
@receivers.clear
3537
nil
@@ -259,6 +261,7 @@ class Channel::Unbuffered(T) < Channel(T)
259261
@value.tap do
260262
@has_value = false
261263
Scheduler.enqueue @sender.not_nil!
264+
@sender = nil
262265
end
263266
end
264267

@@ -269,4 +272,12 @@ class Channel::Unbuffered(T) < Channel(T)
269272
def full?
270273
@has_value || @receivers.empty?
271274
end
275+
276+
def close
277+
super
278+
if sender = @sender
279+
Scheduler.enqueue sender
280+
@sender = nil
281+
end
282+
end
272283
end

0 commit comments

Comments
 (0)