diff --git a/lib/process_shared.rb b/lib/process_shared.rb index 2ef9257..03348c8 100644 --- a/lib/process_shared.rb +++ b/lib/process_shared.rb @@ -29,4 +29,5 @@ require 'process_shared/binary_semaphore' require 'process_shared/mutex' require 'process_shared/condition_variable' require 'process_shared/monitor' +require 'process_shared/monitor_mixin' diff --git a/lib/process_shared/monitor_mixin.rb b/lib/process_shared/monitor_mixin.rb new file mode 100644 index 0000000..de2d06a --- /dev/null +++ b/lib/process_shared/monitor_mixin.rb @@ -0,0 +1,42 @@ +require 'process_shared' + +module ProcessShared + module MonitorMixin + def self.extended(obj) + obj.send :mon_initialize + end + + def mon_enter + @mon_monitor.lock + end + + def mon_exit + @mon_monitor.unlock + end + + def mon_synchronize + mon_enter + begin + yield + ensure + mon_exit + end + end + alias_method :synchronize, :mon_synchronize + + def mon_try_enter + raise NotImplementedError, 'not implemented' + end + alias_method :try_mon_enter, :mon_try_enter + + def new_cond + raise NotImplementedError, 'not implemented' + end + + private + + def mon_initialize + @mon_monitor = Monitor.new + end + end +end diff --git a/spec/process_shared/monitor_mixin_spec.rb b/spec/process_shared/monitor_mixin_spec.rb new file mode 100644 index 0000000..62e0483 --- /dev/null +++ b/spec/process_shared/monitor_mixin_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' +require 'process_shared' + +module ProcessShared + describe MonitorMixin do + + before :each do + @obj = Object.new + @obj.extend(MonitorMixin) + end + + it 'raises exception when unlocked by other process' do + pid = Kernel.fork do + @obj.mon_enter + sleep 0.2 + @obj.mon_exit + Kernel.exit! + end + + sleep 0.1 + proc { @obj.mon_exit }.must_raise(ProcessError) + + ::Process.wait(pid) + end + + it 'raises nothing with nested lock' do + @obj.mon_enter + @obj.mon_enter + @obj.mon_exit + @obj.mon_exit + end + end +end