Skip to content

Instantly share code, notes, and snippets.

@mrnugget
Last active September 7, 2024 14:59
Show Gist options
  • Save mrnugget/4769939 to your computer and use it in GitHub Desktop.
Save mrnugget/4769939 to your computer and use it in GitHub Desktop.
The self-pipe trick in Ruby
#!/usr/bin/env ruby
# Contrived example of self-pipe preventing signal race condition prior to select()
# @see http://cr.yp.to/docs/selfpipe.html
# @author Paul Annesley
SELF_READ, SELF_WRITE = IO.pipe
@run = true
trap :INT do
@run = false
SELF_WRITE.putc(0)
end
# send SIGINT mid-sleep
Process.fork { sleep 1; Process.kill :INT, Process.ppid; exit }
r,w = IO.pipe
while @run do
sleep 0.2 # .. amplify race-condition; exists until select()
w.putc(".") if @run # .. nothing written if SIGINT handler has disabled @run
selected = IO.select [r, SELF_READ]
break if selected.first.include? SELF_READ
print r.getc
end
puts 'without self-pipe, select() would have blocked'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment