Module: Strelka::SignalHandling
- Included in:
- MultiRunner
- Defined in:
- lib/strelka/signal_handling.rb
Overview
A module containing signal-handling logic for the 'start' command line.
Instance Method Summary collapse
-
#ignore_signals(*signals) ⇒ Object
Set all signal handlers to ignore.
-
#reset_signal_traps(*signals) ⇒ Object
Set the signal handlers back to their defaults.
-
#set_signal_traps(*signals) ⇒ Object
Set up signal handlers for common signals that will shut down, restart, etc.
-
#set_up_signal_handling ⇒ Object
Set up data structures for signal handling.
-
#simulate_signal(signal) ⇒ Object
Simulate the receipt of the specified
signal(probably only useful in testing). -
#wait_for_signals(timeout = nil) ⇒ Object
The body of the signal handler.
-
#wake_up ⇒ Object
Wake the main thread up through the self-pipe.
-
#with_signal_handler(*signals) ⇒ Object
Wrap a block in signal-handling.
Instance Method Details
#ignore_signals(*signals) ⇒ Object
Set all signal handlers to ignore.
91 92 93 94 95 96 97 |
# File 'lib/strelka/signal_handling.rb', line 91 def ignore_signals( *signals ) self.log.debug "Ignoring signals." signals.each do |sig| next if sig == :CHLD Signal.trap( sig, :IGNORE ) end end |
#reset_signal_traps(*signals) ⇒ Object
Set the signal handlers back to their defaults.
101 102 103 104 105 106 |
# File 'lib/strelka/signal_handling.rb', line 101 def reset_signal_traps( *signals ) self.log.debug "Restoring default signal handlers." signals.each do |sig| Signal.trap( sig, :DEFAULT ) end end |
#set_signal_traps(*signals) ⇒ Object
Set up signal handlers for common signals that will shut down, restart, etc.
79 80 81 82 83 84 85 86 87 |
# File 'lib/strelka/signal_handling.rb', line 79 def set_signal_traps( *signals ) self.log.debug "Setting up deferred signal handlers." signals.each do |sig| Signal.trap( sig ) do Thread.main[:signal_queue] << sig self.wake_up end end end |
#set_up_signal_handling ⇒ Object
Set up data structures for signal handling.
26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/strelka/signal_handling.rb', line 26 def set_up_signal_handling # Self-pipe for deferred signal-handling (ala djb: # http://cr.yp.to/docs/selfpipe.html) reader, writer = IO.pipe reader.close_on_exec = true writer.close_on_exec = true @selfpipe = { reader: reader, writer: writer } # Set up a global signal queue Thread.main[:signal_queue] = [] end |
#simulate_signal(signal) ⇒ Object
Simulate the receipt of the specified signal (probably only useful
in testing).
111 112 113 114 |
# File 'lib/strelka/signal_handling.rb', line 111 def simulate_signal( signal ) Thread.main[:signal_queue] << signal.to_sym self.wake_up end |
#wait_for_signals(timeout = nil) ⇒ Object
The body of the signal handler. Wait for at least one signal to arrive and
handle it, or timeout and return if a timeout integer is provided. This
should be called inside a loop, either in its own thread or in another loop
that doesn't block anywhere else. Returns true if a signal was handled, or
false if a timeout occurred.
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/strelka/signal_handling.rb', line 44 def wait_for_signals( timeout=nil ) # Wait on the selfpipe for signals # self.log.debug " waiting for the selfpipe" fds = IO.select( [@selfpipe[:reader]], [], [], timeout ) begin rval = @selfpipe[:reader].read_nonblock( 11 ) self.log.debug " read from the selfpipe: %p" % [ rval ] rescue Errno::EAGAIN, Errno::EINTR => err # ignore end # Look for any signals that arrived and handle them while sig = Thread.main[:signal_queue].shift self.log.debug " got a queued signal: %p" % [ sig ] self.handle_signal( sig ) end return fds ? true : false end |
#wake_up ⇒ Object
Wake the main thread up through the self-pipe. Note: since this is a signal-handler method, it needs to be re-entrant.
68 69 70 71 72 73 74 75 |
# File 'lib/strelka/signal_handling.rb', line 68 def wake_up @selfpipe[:writer].write_nonblock('.') rescue Errno::EAGAIN # Ignore. rescue Errno::EINTR # Repeated signal. :TODO: Does this need a counter? retry end |
#with_signal_handler(*signals) ⇒ Object
Wrap a block in signal-handling.
12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/strelka/signal_handling.rb', line 12 def with_signal_handler( *signals ) self.set_up_signal_handling self.set_signal_traps( *signals ) self.start_signal_handler return yield ensure self.stop_signal_handler self.reset_signal_traps( *signals ) end |