Are system signals ( INT, TERM, etc) sent to all threads at the same time? I thought that it would cascade from the parent to the children, but that doesn't seem to be the case. I'm running Sinatra in a child thread. Sinatra traps INT ( Control-C), shuts down the web server, but never exits the thread. Trapping the interrupt at the parent process doesn't seem to have any effect. Thanks, Chris
on 2012-07-13 16:11
on 2012-07-13 19:17
On Fri, Jul 13, 2012 at 7:09 AM, Chris Evans <jruby@rubbletub.com> wrote: > Are system signals ( INT, TERM, etc) sent to all threads at the same > time? I thought that it would cascade from the parent to the > children, but that doesn't seem to be the case. > > I'm running Sinatra in a child thread. Sinatra traps INT ( > Control-C), shuts down the web server, but never exits the thread. > Trapping the interrupt at the parent process doesn't seem to have any > effect. The JVM sets up a separate thread to handle signals, so registering for those events basically just registers a callback to run on that thread. Can you investigate a bit more how MRI does this? We are somewhat limited in how we work within the confines of the JVM, but if there's something we can improve we'll do it. - Charlie
on 2012-07-13 20:21
Signal handlers are global to the whole process and all its threads.
there is only one signal handler per signal defined and the last
installed handler will the one called. note that calling Kernel.trap
returns the previously defined handler.
As far as your specific problem with Sinatra, I tried this minimal
setup and I can't reproduce your problem (JRuby 1.6.7.2). Can you
reproduce the problem in the smallest possible setup and share it?
class Controller < Sinatra::Base
set :port, 8080
get '/' do
"<html><body>Hello World</body></html>"
end
end
t = Thread.new do
Controller.run!
end
t.join
One thing I can say is that Sinatra initializes itself and install its
signal handlers in a at_exit block.
Colin
on 2012-07-13 22:17
Just wanted to add about the Sinatra at_exit initialization: this is when you use Sinatra the "default" way, not by calling Sinatra::Base#run! as in my example. If you want to install your own INT signal handler in my example, you could, by installing it just before the t.join statement, but make sure to wait a bit to make sure Sinatra completes its initialization code before setting up your own trap. Colin On Fri, Jul 13, 2012 at 2:20 PM, Colin Surprenant
on 2012-07-16 20:55
On Fri, Jul 13, 2012 at 2:20 PM, Colin Surprenant <colin.surprenant@gmail.com> wrote: > Signal handlers are global to the whole process and all its threads. > there is only one signal handler per signal defined and the last > installed handler will the one called This ended up being the key. Since Sinatra has a bit of startup time, it was the last thread to register the trap. Once the INT was signaled, Sinatra would shut down, but other threads would continue to execute. I ended up adding an additional thread that waited for Sinatra to start up (Sinatra.running? == true), then registers a new Signal trap to override Sinatra's trap. Code: ------------------------------------------------- require 'sinatra/base' class MySinatraTest < Sinatra::Base get '/' do "hello world" end end threads = Array.new() threads << Thread.new { MySinatraTest.run! } threads << Thread.new { until MySinatraTest.running? sleep 1 end trap("INT") {puts "trapped in subthread"; exit} puts "ok, trap registered" } threads.each do |thread| thread.join end Thanks for the help, Chris
on 2013-05-01 14:52
Chris Evans wrote in post #1068965: > threads << Thread.new { > until MySinatraTest.running? > sleep 1 > end > trap("INT") {puts "trapped in subthread"; exit} > puts "ok, trap registered" > } > threads.each do |thread| > thread.join > end In case this helps someone else, you can also just restore the default signal handler instead of punting it to another thread by using the 'DEFAULT' parameter to Signal.trap, e.g. sleep 1 until MySinatraTest.running? trap(:INT, 'DEFAULT')
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.