summaryrefslogtreecommitdiff
path: root/lib/rbot/ircbot.rb
diff options
context:
space:
mode:
authorMatthias H <apoc@sixserv.org>2013-09-04 02:38:10 +0200
committerGiuseppe Bilotta <giuseppe.bilotta@gmail.com>2013-11-02 11:30:39 +0100
commitfa08e1bd0b4c915add758931a5b47d2c74ebddc0 (patch)
tree5d8477f27d04daa91f77faf4d075f214442b9566 /lib/rbot/ircbot.rb
parente9b652aa2a047557aaa1a68278d9d402f56d45b2 (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.rb40
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