pda (owner)

Revisions

gist: 229916 Download_button fork
public
Public Clone URL: git://gist.github.com/229916.git
Embed All Files: show embed
selfpipe.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/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
 
def simulate_external_write
  w.putc(0) if @run # .. simulates SIGINT preventing write
end
 
# send SIGINT mid-sleep
Process.fork { sleep 0.1; Process.kill :INT, Process.ppid; exit }
 
r,w = IO.pipe
while @run do
  sleep 0.2 # .. amplify race-condition; exists until select()
  simulate_external_write
  selected = IO.select [r, SELF_READ]
  break if selected.first.include? SELF_READ
  r.getc
end
 
puts 'without self-pipe, select() would have blocked'