aboutsummaryrefslogtreecommitdiffstats
path: root/test/test_sync.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_sync.rb')
-rw-r--r--test/test_sync.rb69
1 files changed, 69 insertions, 0 deletions
diff --git a/test/test_sync.rb b/test/test_sync.rb
new file mode 100644
index 0000000000..e3294ff824
--- /dev/null
+++ b/test/test_sync.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: false
+require 'test/unit'
+require 'sync'
+require 'timeout'
+
+class SyncTest < Test::Unit::TestCase
+ class Tester
+ include Sync_m
+ end
+
+ def test_sync_lock_and_wakeup
+ tester = Tester.new
+
+ tester.sync_lock(:EX)
+
+ t = Thread.new { tester.sync_lock(:EX) }
+
+ sleep 0.1 until t.stop?
+ t.wakeup
+ sleep 0.1 until t.stop?
+
+ assert_equal(tester.sync_waiting.uniq, tester.sync_waiting)
+ ensure
+ t.kill
+ t.join
+ end
+
+ def test_sync_upgrade_and_wakeup
+ tester = Tester.new
+ tester.sync_lock(:SH)
+
+ t = Thread.new do
+ tester.sync_lock(:SH)
+ tester.sync_lock(:EX)
+ end
+
+ sleep 0.1 until t.stop?
+ t.wakeup
+ sleep 0.1 until t.stop?
+
+ tester.sync_upgrade_waiting.each { |ary|
+ assert(!tester.sync_waiting.include?(ary[0]))
+ }
+ assert_equal(tester.sync_waiting.uniq, tester.sync_waiting)
+ assert_equal(tester.sync_waiting, [])
+ ensure
+ t.kill
+ t.join
+ end
+
+ def test_sync_lock_and_raise
+ tester= Tester.new
+ tester.sync_lock(:EX)
+
+ t = Thread.new {
+ assert_raise(RuntimeError) {
+ tester.sync_lock(:EX)
+ }
+ }
+
+ sleep 0.1 until t.stop?
+ sleep 1 if RubyVM::MJIT.enabled? # t.stop? behaves unexpectedly with --jit-wait
+ t.raise
+ t.join
+
+ assert_equal(tester.sync_waiting.uniq, tester.sync_waiting)
+ assert_equal(tester.sync_waiting, [])
+ end
+end