diff options
author | Matthias H <apoc@sixserv.org> | 2013-09-04 02:38:10 +0200 |
---|---|---|
committer | Giuseppe Bilotta <giuseppe.bilotta@gmail.com> | 2013-11-02 11:30:39 +0100 |
commit | fa08e1bd0b4c915add758931a5b47d2c74ebddc0 (patch) | |
tree | 5d8477f27d04daa91f77faf4d075f214442b9566 /lib/rbot/ircbot.rb | |
parent | e9b652aa2a047557aaa1a68278d9d402f56d45b2 (diff) |
ruby 2.0.0: changes sigtrapping, fixes ThreadError
Ruby 2.0.0 crashes with "ThreadError: can't be called from trap context"
anytime a signal is received, because it tries to write a debug message
within the "trap context".
This changes signal handling so that signals are queued and processed
in the main loop.
More information: https://www.ruby-forum.com/topic/4411227
Diffstat (limited to 'lib/rbot/ircbot.rb')
-rw-r--r-- | lib/rbot/ircbot.rb | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/lib/rbot/ircbot.rb b/lib/rbot/ircbot.rb index 92f5fe55..5713d175 100644 --- a/lib/rbot/ircbot.rb +++ b/lib/rbot/ircbot.rb @@ -801,6 +801,7 @@ class Bot :purge_split => @config['send.purge_split'], :truncate_text => @config['send.truncate_text'].dup + @signals = [] trap_sigs end @@ -904,26 +905,35 @@ class Bot end # things to do when we receive a signal - def got_sig(sig, func=:quit) - debug "received #{sig}, queueing #{func}" - # this is not an interruption if we just need to reconnect - $interrupted += 1 unless func == :reconnect - self.send(func) unless @quit_mutex.locked? - debug "interrupted #{$interrupted} times" - if $interrupted >= 3 - debug "drastic!" - log_session_end - exit 2 + def handle_sigs + while sig = @signals.shift + func = case sig + when 'SIGHUP' + :restart + when 'SIGUSR1' + :reconnect + else + :quit + end + debug "received #{sig}, queueing #{func}" + # this is not an interruption if we just need to reconnect + $interrupted += 1 unless func == :reconnect + self.send(func) unless @quit_mutex.locked? + debug "interrupted #{$interrupted} times" + if $interrupted >= 3 + debug "drastic!" + log_session_end + exit 2 + end end end # trap signals def trap_sigs begin - trap("SIGINT") { got_sig("SIGINT") } - trap("SIGTERM") { got_sig("SIGTERM") } - trap("SIGHUP") { got_sig("SIGHUP", :restart) } - trap("SIGUSR1") { got_sig("SIGUSR1", :reconnect) } + %w(SIGINT SIGTERM SIGHUP SIGUSR1).each do |sig| + trap(sig) { @signals << sig } + end rescue ArgumentError => e debug "failed to trap signals (#{e.pretty_inspect}): running on Windows?" rescue Exception => e @@ -1006,10 +1016,12 @@ class Bot quit_msg = nil valid_recv = false # did we receive anything (valid) from the server yet? begin + handle_sigs reconnect(quit_msg, too_fast) quit if $interrupted > 0 valid_recv = false while @socket.connected? + handle_sigs quit if $interrupted > 0 # Wait for messages and process them as they arrive. If nothing is |