summaryrefslogtreecommitdiff
path: root/test/fiber/test_mutex.rb
diff options
context:
space:
mode:
authorBenoit Daloze <eregontp@gmail.com>2020-09-05 16:26:24 +1200
committerSamuel Williams <samuel.williams@oriontransfer.co.nz>2020-09-14 16:44:09 +1200
commit178c1b0922dc727897d81d7cfe9c97d5ffa97fd9 (patch)
tree113600e7e6a196b779bcac7529535597858f78a7 /test/fiber/test_mutex.rb
parent9e0a48c7a31ecd39be0596d0517b9d521ae75282 (diff)
downloadruby-178c1b0922dc727897d81d7cfe9c97d5ffa97fd9.tar.gz
Make Mutex per-Fiber instead of per-Thread
* Enables Mutex to be used as synchronization between multiple Fibers of the same Thread. * With a Fiber scheduler we can yield to another Fiber on contended Mutex#lock instead of blocking the entire thread. * This also makes the behavior of Mutex consistent across CRuby, JRuby and TruffleRuby. * [Feature #16792]
Diffstat (limited to 'test/fiber/test_mutex.rb')
-rw-r--r--test/fiber/test_mutex.rb38
1 files changed, 33 insertions, 5 deletions
diff --git a/test/fiber/test_mutex.rb b/test/fiber/test_mutex.rb
index 5179959a6a..393a44fc2f 100644
--- a/test/fiber/test_mutex.rb
+++ b/test/fiber/test_mutex.rb
@@ -14,7 +14,7 @@ class TestFiberMutex < Test::Unit::TestCase
assert_equal Thread.scheduler, scheduler
mutex.synchronize do
- assert_nil Thread.scheduler
+ assert Thread.scheduler
end
end
end
@@ -22,7 +22,35 @@ class TestFiberMutex < Test::Unit::TestCase
thread.join
end
+ def test_mutex_interleaved_locking
+ mutex = Mutex.new
+
+ thread = Thread.new do
+ scheduler = Scheduler.new
+ Thread.current.scheduler = scheduler
+
+ Fiber.schedule do
+ mutex.lock
+ sleep 0.1
+ mutex.unlock
+ end
+
+ Fiber.schedule do
+ mutex.lock
+ sleep 0.1
+ mutex.unlock
+ end
+
+ scheduler.run
+ end
+
+ thread.join
+ end
+
def test_mutex_deadlock
+ err = /No live threads left. Deadlock\?/
+ assert_in_out_err %W[-I#{__dir__} -], <<-RUBY, ['in synchronize'], err, success: false
+ require 'scheduler'
mutex = Mutex.new
thread = Thread.new do
@@ -30,18 +58,18 @@ class TestFiberMutex < Test::Unit::TestCase
Thread.current.scheduler = scheduler
Fiber.schedule do
- assert_equal Thread.scheduler, scheduler
+ raise unless Thread.scheduler == scheduler
mutex.synchronize do
+ puts 'in synchronize'
Fiber.yield
end
end
- assert_raise ThreadError do
- mutex.lock
- end
+ mutex.lock
end
thread.join
+ RUBY
end
end