Browse files

Setup locking around Process.kill process

This fixes a potential race that could occur in this subprocess. The
problem is that when two signals were received at the same time, there
was a race condition.

What could happen is that when two signals were received, it would run
the signal handler twice. One handler could set signaled to true, the
other one would see signaled as false and exit before the other handler
would print the "signaled" string.

With a Mutex we can use try_lock to attempt to lock once and then exit.
This makes sure we only print "signaled" once and immediately exit.

Why not use Mutex.synchronize {} one might ask here. Well, that doesn't
work since signals are handled in the same thread, so what happens then
is that you can recursive locking errors since the Mutex is locked twice
in the same thread so the deadlock detection kicks in and causes an
  • Loading branch information...
1 parent cb13394 commit 571873850cfb23fc3ec1fdebe8d8678602c4f4d0 @dbussink dbussink committed Jun 21, 2012
Showing with 5 additions and 6 deletions.
  1. +5 −6 spec/ruby/core/process/fixtures/kill.rb
@@ -1,3 +1,5 @@
+require 'thread'
pid_file = ARGV.shift
scenario = ARGV.shift
ruby_exe = ARGV.shift
@@ -7,16 +9,13 @@
# instead, which will likely abort the specs process.
Process.setsid if scenario
-signaled = false
+mutex =
Signal.trap(:TERM) do
- unless signaled
- signaled = true
+ if mutex.try_lock
puts "signaled"
+ Process.exit!
- exit
end, "wb") { |f| f.puts }

0 comments on commit 5718738

Please sign in to comment.