diff options
author | Dan Kubb <dan.kubb@gmail.com> | 2015-03-25 20:54:55 -0700 |
---|---|---|
committer | Dan Kubb <dan.kubb@gmail.com> | 2015-03-25 20:54:55 -0700 |
commit | d5201119feaa2ed0fcaa37ae5fa1a293afafc437 (patch) | |
tree | 1afaf808ae18a3a667678784b4410574610e30ea /test/spec_lock.rb | |
parent | 4d03a0c7bf8dfcde3adbc759bd00a262ab4a15df (diff) | |
download | rack-d5201119feaa2ed0fcaa37ae5fa1a293afafc437.tar.gz |
Fix Rack::Lock mutex usage
* In the previous code if a lock is being waited on and an error was
raised, such as by Rack::Timeout, the original code would attempt to
unlock a mutex it does not own raising a ThreadError with the error
message "Attempt to unlock a mutex which is locked by another thread"
This code uses an explicit begin block that starts immediately after
the mutex is locked so that when the ensure part runs we know that
the mutex belongs to this thread.
Diffstat (limited to 'test/spec_lock.rb')
-rw-r--r-- | test/spec_lock.rb | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/test/spec_lock.rb b/test/spec_lock.rb index 0cbb5447..4a44a0b4 100644 --- a/test/spec_lock.rb +++ b/test/spec_lock.rb @@ -161,4 +161,17 @@ describe Rack::Lock do }.new(lambda { |env| [200, {"Content-Type" => "text/plain"}, %w{ a b c }] }) Rack::Lint.new(app).call(Rack::MockRequest.env_for("/")) end + + should 'not unlock if an error is raised before the mutex is locked' do + lock = Class.new do + def initialize() @unlocked = false end + def unlocked?() @unlocked end + def lock() raise Exception end + def unlock() @unlocked = true end + end.new + env = Rack::MockRequest.env_for("/") + app = lock_app(proc { [200, {"Content-Type" => "text/plain"}, []] }, lock) + lambda { app.call(env) }.should.raise(Exception) + lock.unlocked?.should.equal false + end end |