зеркало из https://github.com/github/ruby.git
* test/ruby/test_thread.rb: move ConditionVariable related test
into test/thread/test_cv.rb. * test/thread/test_cv.rb: new file. * test/thread/test_cv.rb (test_condvar_empty_signal): new tests. * test/thread/test_cv.rb (test_condvar_empty_broadcast): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38111 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
afbbcd133c
Коммит
89ff44e22e
|
@ -1,3 +1,11 @@
|
||||||
|
Sat Dec 1 16:40:22 2012 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
||||||
|
|
||||||
|
* test/ruby/test_thread.rb: move ConditionVariable related test
|
||||||
|
into test/thread/test_cv.rb.
|
||||||
|
* test/thread/test_cv.rb: new file.
|
||||||
|
* test/thread/test_cv.rb (test_condvar_empty_signal): new tests.
|
||||||
|
* test/thread/test_cv.rb (test_condvar_empty_broadcast): ditto.
|
||||||
|
|
||||||
Sat Dec 1 15:14:25 2012 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
Sat Dec 1 15:14:25 2012 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
||||||
|
|
||||||
* test/ruby/test_thread.rb (test_cv_wait_deadlock): enable
|
* test/ruby/test_thread.rb (test_cv_wait_deadlock): enable
|
||||||
|
|
|
@ -120,174 +120,6 @@ class TestThread < Test::Unit::TestCase
|
||||||
assert_equal(max * max * max, r)
|
assert_equal(max * max * max, r)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_condvar
|
|
||||||
mutex = Mutex.new
|
|
||||||
condvar = ConditionVariable.new
|
|
||||||
result = []
|
|
||||||
mutex.synchronize do
|
|
||||||
t = Thread.new do
|
|
||||||
mutex.synchronize do
|
|
||||||
result << 1
|
|
||||||
condvar.signal
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
result << 0
|
|
||||||
condvar.wait(mutex)
|
|
||||||
result << 2
|
|
||||||
t.join
|
|
||||||
end
|
|
||||||
assert_equal([0, 1, 2], result)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_condvar_wait_exception_handling
|
|
||||||
# Calling wait in the only thread running should raise a ThreadError of
|
|
||||||
# 'stopping only thread'
|
|
||||||
mutex = Mutex.new
|
|
||||||
condvar = ConditionVariable.new
|
|
||||||
|
|
||||||
locked = false
|
|
||||||
thread = Thread.new do
|
|
||||||
Thread.current.abort_on_exception = false
|
|
||||||
mutex.synchronize do
|
|
||||||
begin
|
|
||||||
condvar.wait(mutex)
|
|
||||||
rescue Exception
|
|
||||||
locked = mutex.locked?
|
|
||||||
raise
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
until thread.stop?
|
|
||||||
sleep(0.1)
|
|
||||||
end
|
|
||||||
|
|
||||||
thread.raise Interrupt, "interrupt a dead condition variable"
|
|
||||||
assert_raise(Interrupt) { thread.value }
|
|
||||||
assert(locked)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_condvar_wait_and_broadcast
|
|
||||||
nr_threads = 3
|
|
||||||
threads = Array.new
|
|
||||||
mutex = Mutex.new
|
|
||||||
condvar = ConditionVariable.new
|
|
||||||
result = []
|
|
||||||
|
|
||||||
nr_threads.times do |i|
|
|
||||||
threads[i] = Thread.new do
|
|
||||||
mutex.synchronize do
|
|
||||||
result << "C1"
|
|
||||||
condvar.wait mutex
|
|
||||||
result << "C2"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
sleep 0.1
|
|
||||||
mutex.synchronize do
|
|
||||||
result << "P1"
|
|
||||||
condvar.broadcast
|
|
||||||
result << "P2"
|
|
||||||
end
|
|
||||||
nr_threads.times do |i|
|
|
||||||
threads[i].join
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_equal ["C1", "C1", "C1", "P1", "P2", "C2", "C2", "C2"], result
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_condvar_wait_deadlock
|
|
||||||
assert_in_out_err([], <<-INPUT, ["No live threads left. Deadlock?"], [])
|
|
||||||
require "thread"
|
|
||||||
|
|
||||||
mutex = Mutex.new
|
|
||||||
cv = ConditionVariable.new
|
|
||||||
|
|
||||||
mesg = nil
|
|
||||||
begin
|
|
||||||
mutex.lock
|
|
||||||
cv.wait mutex
|
|
||||||
mutex.unlock
|
|
||||||
rescue Exception => e
|
|
||||||
mesg = e.message
|
|
||||||
end
|
|
||||||
print mesg
|
|
||||||
INPUT
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_condvar_wait_deadlock_2
|
|
||||||
nr_threads = 3
|
|
||||||
threads = Array.new
|
|
||||||
mutex = Mutex.new
|
|
||||||
condvar = ConditionVariable.new
|
|
||||||
|
|
||||||
nr_threads.times do |i|
|
|
||||||
if (i != 0)
|
|
||||||
mutex.unlock
|
|
||||||
end
|
|
||||||
threads[i] = Thread.new do
|
|
||||||
mutex.synchronize do
|
|
||||||
condvar.wait mutex
|
|
||||||
end
|
|
||||||
end
|
|
||||||
mutex.lock
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_raise(Timeout::Error) do
|
|
||||||
Timeout.timeout(0.1) { condvar.wait mutex }
|
|
||||||
end
|
|
||||||
mutex.unlock
|
|
||||||
threads.each(&:kill)
|
|
||||||
threads.each(&:join)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_condvar_timed_wait
|
|
||||||
mutex = Mutex.new
|
|
||||||
condvar = ConditionVariable.new
|
|
||||||
timeout = 0.3
|
|
||||||
locked = false
|
|
||||||
|
|
||||||
t0 = Time.now
|
|
||||||
mutex.synchronize do
|
|
||||||
begin
|
|
||||||
condvar.wait(mutex, timeout)
|
|
||||||
ensure
|
|
||||||
locked = mutex.locked?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
t1 = Time.now
|
|
||||||
t = t1-t0
|
|
||||||
|
|
||||||
assert_operator(timeout*0.9, :<, t)
|
|
||||||
assert(locked)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_condvar_nolock
|
|
||||||
mutex = Mutex.new
|
|
||||||
condvar = ConditionVariable.new
|
|
||||||
|
|
||||||
assert_raise(ThreadError) {condvar.wait(mutex)}
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_condvar_nolock_2
|
|
||||||
mutex = Mutex.new
|
|
||||||
condvar = ConditionVariable.new
|
|
||||||
|
|
||||||
Thread.new do
|
|
||||||
assert_raise(ThreadError) {condvar.wait(mutex)}
|
|
||||||
end.join
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_condvar_nolock_3
|
|
||||||
mutex = Mutex.new
|
|
||||||
condvar = ConditionVariable.new
|
|
||||||
|
|
||||||
Thread.new do
|
|
||||||
assert_raise(ThreadError) {condvar.wait(mutex, 0.1)}
|
|
||||||
end.join
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_local_barrier
|
def test_local_barrier
|
||||||
dir = File.dirname(__FILE__)
|
dir = File.dirname(__FILE__)
|
||||||
lbtest = File.join(dir, "lbtest.rb")
|
lbtest = File.join(dir, "lbtest.rb")
|
||||||
|
|
|
@ -0,0 +1,188 @@
|
||||||
|
require 'test/unit'
|
||||||
|
require 'thread'
|
||||||
|
require 'tmpdir'
|
||||||
|
require_relative '../ruby/envutil'
|
||||||
|
|
||||||
|
class TestConditionVariable < Test::Unit::TestCase
|
||||||
|
def test_condvar_signal_and_wait
|
||||||
|
mutex = Mutex.new
|
||||||
|
condvar = ConditionVariable.new
|
||||||
|
result = []
|
||||||
|
mutex.synchronize do
|
||||||
|
t = Thread.new do
|
||||||
|
mutex.synchronize do
|
||||||
|
result << 1
|
||||||
|
condvar.signal
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
result << 0
|
||||||
|
condvar.wait(mutex)
|
||||||
|
result << 2
|
||||||
|
t.join
|
||||||
|
end
|
||||||
|
assert_equal([0, 1, 2], result)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_condvar_wait_exception_handling
|
||||||
|
# Calling wait in the only thread running should raise a ThreadError of
|
||||||
|
# 'stopping only thread'
|
||||||
|
mutex = Mutex.new
|
||||||
|
condvar = ConditionVariable.new
|
||||||
|
|
||||||
|
locked = false
|
||||||
|
thread = Thread.new do
|
||||||
|
Thread.current.abort_on_exception = false
|
||||||
|
mutex.synchronize do
|
||||||
|
begin
|
||||||
|
condvar.wait(mutex)
|
||||||
|
rescue Exception
|
||||||
|
locked = mutex.locked?
|
||||||
|
raise
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
until thread.stop?
|
||||||
|
sleep(0.1)
|
||||||
|
end
|
||||||
|
|
||||||
|
thread.raise Interrupt, "interrupt a dead condition variable"
|
||||||
|
assert_raise(Interrupt) { thread.value }
|
||||||
|
assert(locked)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_condvar_wait_and_broadcast
|
||||||
|
nr_threads = 3
|
||||||
|
threads = Array.new
|
||||||
|
mutex = Mutex.new
|
||||||
|
condvar = ConditionVariable.new
|
||||||
|
result = []
|
||||||
|
|
||||||
|
nr_threads.times do |i|
|
||||||
|
threads[i] = Thread.new do
|
||||||
|
mutex.synchronize do
|
||||||
|
result << "C1"
|
||||||
|
condvar.wait mutex
|
||||||
|
result << "C2"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
sleep 0.1
|
||||||
|
mutex.synchronize do
|
||||||
|
result << "P1"
|
||||||
|
condvar.broadcast
|
||||||
|
result << "P2"
|
||||||
|
end
|
||||||
|
nr_threads.times do |i|
|
||||||
|
threads[i].join
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal ["C1", "C1", "C1", "P1", "P2", "C2", "C2", "C2"], result
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_condvar_wait_deadlock
|
||||||
|
assert_in_out_err([], <<-INPUT, ["No live threads left. Deadlock?"], [])
|
||||||
|
require "thread"
|
||||||
|
|
||||||
|
mutex = Mutex.new
|
||||||
|
cv = ConditionVariable.new
|
||||||
|
|
||||||
|
mesg = nil
|
||||||
|
begin
|
||||||
|
mutex.lock
|
||||||
|
cv.wait mutex
|
||||||
|
mutex.unlock
|
||||||
|
rescue Exception => e
|
||||||
|
mesg = e.message
|
||||||
|
end
|
||||||
|
print mesg
|
||||||
|
INPUT
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_condvar_wait_deadlock_2
|
||||||
|
nr_threads = 3
|
||||||
|
threads = Array.new
|
||||||
|
mutex = Mutex.new
|
||||||
|
condvar = ConditionVariable.new
|
||||||
|
|
||||||
|
nr_threads.times do |i|
|
||||||
|
if (i != 0)
|
||||||
|
mutex.unlock
|
||||||
|
end
|
||||||
|
threads[i] = Thread.new do
|
||||||
|
mutex.synchronize do
|
||||||
|
condvar.wait mutex
|
||||||
|
end
|
||||||
|
end
|
||||||
|
mutex.lock
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_raise(Timeout::Error) do
|
||||||
|
Timeout.timeout(0.1) { condvar.wait mutex }
|
||||||
|
end
|
||||||
|
mutex.unlock
|
||||||
|
threads.each(&:kill)
|
||||||
|
threads.each(&:join)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_condvar_timed_wait
|
||||||
|
mutex = Mutex.new
|
||||||
|
condvar = ConditionVariable.new
|
||||||
|
timeout = 0.3
|
||||||
|
locked = false
|
||||||
|
|
||||||
|
t0 = Time.now
|
||||||
|
mutex.synchronize do
|
||||||
|
begin
|
||||||
|
condvar.wait(mutex, timeout)
|
||||||
|
ensure
|
||||||
|
locked = mutex.locked?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
t1 = Time.now
|
||||||
|
t = t1-t0
|
||||||
|
|
||||||
|
assert_operator(timeout*0.9, :<, t)
|
||||||
|
assert(locked)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_condvar_nolock
|
||||||
|
mutex = Mutex.new
|
||||||
|
condvar = ConditionVariable.new
|
||||||
|
|
||||||
|
assert_raise(ThreadError) {condvar.wait(mutex)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_condvar_nolock_2
|
||||||
|
mutex = Mutex.new
|
||||||
|
condvar = ConditionVariable.new
|
||||||
|
|
||||||
|
Thread.new do
|
||||||
|
assert_raise(ThreadError) {condvar.wait(mutex)}
|
||||||
|
end.join
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_condvar_nolock_3
|
||||||
|
mutex = Mutex.new
|
||||||
|
condvar = ConditionVariable.new
|
||||||
|
|
||||||
|
Thread.new do
|
||||||
|
assert_raise(ThreadError) {condvar.wait(mutex, 0.1)}
|
||||||
|
end.join
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_condvar_empty_signal
|
||||||
|
mutex = Mutex.new
|
||||||
|
condvar = ConditionVariable.new
|
||||||
|
|
||||||
|
assert_nothing_raised(Exception) { mutex.synchronize {condvar.signal} }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_condvar_empty_broadcast
|
||||||
|
mutex = Mutex.new
|
||||||
|
condvar = ConditionVariable.new
|
||||||
|
|
||||||
|
assert_nothing_raised(Exception) { mutex.synchronize {condvar.broadcast} }
|
||||||
|
end
|
||||||
|
end
|
Загрузка…
Ссылка в новой задаче