83 lines
1.8 KiB
Ruby
83 lines
1.8 KiB
Ruby
require 'spec_helper'
|
|
require 'process_shared/mutex'
|
|
require 'process_shared/shared_memory'
|
|
|
|
module ProcessShared
|
|
describe Mutex do
|
|
it 'protects access to a shared variable' do
|
|
mutex = Mutex.new
|
|
mem = SharedMemory.new(:char)
|
|
mem.put_char(0, 0)
|
|
|
|
pids = []
|
|
10.times do |i|
|
|
inc = (-1) ** i # half the procs increment; half decrement
|
|
pids << fork do
|
|
10.times do
|
|
mutex.lock
|
|
begin
|
|
mem.put_char(0, mem.get_char(0) + inc)
|
|
sleep 0.001
|
|
ensure
|
|
mutex.unlock
|
|
end
|
|
end
|
|
Kernel.exit!
|
|
end
|
|
end
|
|
|
|
pids.each { |pid| ::Process.wait(pid) }
|
|
|
|
mem.get_char(0).must_equal(0)
|
|
end
|
|
|
|
it 'protects access to a shared variable with synchronize' do
|
|
mutex = Mutex.new
|
|
mem = SharedMemory.new(:char)
|
|
mem.put_char(0, 0)
|
|
|
|
pids = []
|
|
10.times do |i|
|
|
inc = (-1) ** i # half the procs increment; half decrement
|
|
pids << fork do
|
|
10.times do
|
|
mutex.synchronize do
|
|
mem.put_char(0, mem.get_char(0) + inc)
|
|
sleep 0.001
|
|
end
|
|
end
|
|
Kernel.exit!
|
|
end
|
|
end
|
|
|
|
pids.each { |pid| ::Process.wait(pid) }
|
|
|
|
mem.get_char(0).must_equal(0)
|
|
end
|
|
|
|
it 'raises exception when unlocked by other process' do
|
|
mutex = Mutex.new
|
|
|
|
pid = Kernel.fork do
|
|
mutex.lock
|
|
sleep 0.2
|
|
mutex.unlock
|
|
Kernel.exit!
|
|
end
|
|
|
|
sleep 0.1
|
|
proc { mutex.unlock }.must_raise(ProcessError)
|
|
|
|
::Process.wait(pid)
|
|
end
|
|
|
|
it 'raises exception when locked twice by same process' do
|
|
mutex = Mutex.new
|
|
|
|
mutex.lock
|
|
proc { mutex.lock }.must_raise(ProcessError)
|
|
mutex.unlock
|
|
end
|
|
end
|
|
end
|