summaryrefslogtreecommitdiff
path: root/test/spec_lock.rb
diff options
context:
space:
mode:
authorDan Kubb <dan.kubb@gmail.com>2015-03-25 20:54:55 -0700
committerDan Kubb <dan.kubb@gmail.com>2015-03-25 20:54:55 -0700
commitd5201119feaa2ed0fcaa37ae5fa1a293afafc437 (patch)
tree1afaf808ae18a3a667678784b4410574610e30ea /test/spec_lock.rb
parent4d03a0c7bf8dfcde3adbc759bd00a262ab4a15df (diff)
downloadrack-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.rb13
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