Skip to content

Instantly share code, notes, and snippets.

@straight-shoota
Last active October 30, 2024 17:27
Show Gist options
  • Save straight-shoota/e3e5b2c62b0dc26888a4f2915efad521 to your computer and use it in GitHub Desktop.
Save straight-shoota/e3e5b2c62b0dc26888a4f2915efad521 to your computer and use it in GitHub Desktop.
Examples for breaking concurrency-safety in Crystal stdlib
ary = [1, 2, 3]
ch = Channel(Nil).new
spawn do
loop do
ch.receive
ary.shift
end
end
ary.map do |i|
ch.send nil
i
end # => [1, 3, 0]
que = Deque{1, 2, 3}
ch = Channel(Nil).new
spawn do
loop do
ch.receive
que.pop
end
end
que.map do |i|
ch.send nil
i
end # => [1, 2, 0]
class StallingIO < IO
include IO::Buffered
@buffer_size = 4
def initialize(@channel : Channel(Nil), @buffer : IO)
end
def unbuffered_read(slice : Bytes)
end
def unbuffered_write(slice : Bytes)
@channel.send(nil)
@buffer.write(slice)
slice.size
end
def unbuffered_flush
end
def unbuffered_close
end
def unbuffered_rewind
end
end
ch = Channel(Nil).new
buffer = IO::Memory.new
io = StallingIO.new(ch, buffer)
spawn do
while true
ch.receive
spawn do
loop { ch.receive }
end
5.times do |i|
io << "#{i}#{i}"
end
end
end
5.times do |i|
io << "(#{i})"
end
io.flush
buffer.rewind
puts buffer.to_s # => "(0)(1)0011223(2)344)(3)(4)"
# ^ ^ ^
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment