jstorimer/spin — pull request #85 by jdelStrother (2013-07-31 22:32:57+00:00)
Title: Signal handlers

In Ruby 2.0, when I hit Ctrl-\ to re-run my last spec, I get the following:

```
^\log writing failed. can't be called from trap context
/Users/jon/.rvm/gems/ruby-2.0.0-p247/bundler/gems/rails-a9d4fa337af4/activesupport/lib/active_support/dependencies.rb:251:in `require': can't be called from trap context (ThreadError)
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/bundler/gems/rails-a9d4fa337af4/activesupport/lib/active_support/dependencies.rb:251:in `block in require'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/bundler/gems/rails-a9d4fa337af4/activesupport/lib/active_support/dependencies.rb:236:in `load_dependency'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/bundler/gems/rails-a9d4fa337af4/activesupport/lib/active_support/dependencies.rb:251:in `require'
from /Users/jon/Developer/web/spec/helpers/comments_helper_spec.rb:1:in `'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/bundler/gems/rails-a9d4fa337af4/activesupport/lib/active_support/dependencies.rb:245:in `load'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/bundler/gems/rails-a9d4fa337af4/activesupport/lib/active_support/dependencies.rb:245:in `block in load'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/bundler/gems/rails-a9d4fa337af4/activesupport/lib/active_support/dependencies.rb:236:in `load_dependency'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/bundler/gems/rails-a9d4fa337af4/activesupport/lib/active_support/dependencies.rb:245:in `load'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/gems/rspec-core-2.12.2/lib/rspec/core/configuration.rb:789:in `block in load_spec_files'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/gems/rspec-core-2.12.2/lib/rspec/core/configuration.rb:789:in `each'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/gems/rspec-core-2.12.2/lib/rspec/core/configuration.rb:789:in `load_spec_files'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/gems/rspec-core-2.12.2/lib/rspec/core/command_line.rb:22:in `run'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/gems/rspec-core-2.12.2/lib/rspec/core/runner.rb:80:in `run'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/gems/rspec-core-2.12.2/lib/rspec/core/runner.rb:17:in `block in autorun'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/gems/spin-0.7.0/lib/spin.rb:321:in `fork'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/gems/spin-0.7.0/lib/spin.rb:321:in `fork_and_run'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/gems/spin-0.7.0/lib/spin.rb:197:in `sigquit_handler'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/gems/spin-0.7.0/lib/spin.rb:178:in `block in rerun_last_tests_on_quit'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/gems/spin-0.7.0/lib/spin.rb:145:in `call'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/gems/spin-0.7.0/lib/spin.rb:145:in `accept'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/gems/spin-0.7.0/lib/spin.rb:145:in `run_pushed_tests'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/gems/spin-0.7.0/lib/spin.rb:42:in `block (2 levels) in serve'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/gems/spin-0.7.0/lib/spin.rb:41:in `loop'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/gems/spin-0.7.0/lib/spin.rb:41:in `block in serve'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/gems/spin-0.7.0/lib/spin.rb:257:in `open_socket'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/gems/spin-0.7.0/lib/spin.rb:36:in `serve'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/gems/spin-0.7.0/lib/spin/cli.rb:43:in `run'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/gems/spin-0.7.0/bin/spin:3:in `'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/bin/spin:23:in `load'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/bin/spin:23:in `

'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/bin/ruby_noexec_wrapper:14:in `eval'
from /Users/jon/.rvm/gems/ruby-2.0.0-p247/bin/ruby_noexec_wrapper:14:in `

'
log writing failed. can't be called from trap context
```

This PR replaces the signal handling behaviour with the self-pipe trick (https://gist.github.com/mrnugget/4769939), moving the invocation of sigquit_handler() & sigint_handler() to the main event loop.

The first commit in this PR is mostly just shuffling code around so that the changes in the second commit are clearer. I could squash them into a single one if you like. Would welcome any comments on the cleanness/correctness of the code.