diff --git a/Gemfile b/Gemfile index f86c8fbd4..740894e73 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ group :development do gem 'rake', '~> 10.4.2' gem 'rake-compiler', '~> 0.9.5' gem 'gem-compiler', '~> 0.3.0' - gem 'benchmark-ips' + gem 'benchmark-ips', '~> 2.1.1' end group :testing do diff --git a/ext/com/concurrent_ruby/ext/AtomicReferenceLibrary.java b/ext/com/concurrent_ruby/ext/AtomicReferenceLibrary.java index fce3636be..dfa9e7704 100644 --- a/ext/com/concurrent_ruby/ext/AtomicReferenceLibrary.java +++ b/ext/com/concurrent_ruby/ext/AtomicReferenceLibrary.java @@ -25,7 +25,7 @@ public class AtomicReferenceLibrary implements Library { public void load(Ruby runtime, boolean wrap) throws IOException { RubyModule concurrentMod = runtime.defineModule("Concurrent"); - RubyClass atomicCls = concurrentMod.defineClassUnder("JavaAtomic", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR); + RubyClass atomicCls = concurrentMod.defineClassUnder("JavaAtomicReference", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR); try { sun.misc.Unsafe.class.getMethod("getAndSetObject", Object.class); atomicCls.setAllocator(JRUBYREFERENCE8_ALLOCATOR); diff --git a/ext/concurrent/rb_concurrent.c b/ext/concurrent/rb_concurrent.c index e927ab4f8..5f1ee3293 100644 --- a/ext/concurrent/rb_concurrent.c +++ b/ext/concurrent/rb_concurrent.c @@ -7,7 +7,7 @@ // module and class definitions static VALUE rb_mConcurrent; -static VALUE rb_cAtomic; +static VALUE rb_cAtomicReference; static VALUE rb_cAtomicBoolean; static VALUE rb_cAtomicFixnum; @@ -17,20 +17,20 @@ void Init_extension() { // define modules and classes rb_mConcurrent = rb_define_module("Concurrent"); - rb_cAtomic = rb_define_class_under(rb_mConcurrent, "CAtomic", rb_cObject); + rb_cAtomicReference = rb_define_class_under(rb_mConcurrent, "CAtomicReference", rb_cObject); rb_cAtomicBoolean = rb_define_class_under(rb_mConcurrent, "CAtomicBoolean", rb_cObject); rb_cAtomicFixnum = rb_define_class_under(rb_mConcurrent, "CAtomicFixnum", rb_cObject); - // CAtomic - rb_define_alloc_func(rb_cAtomic, ir_alloc); - rb_define_method(rb_cAtomic, "initialize", ir_initialize, -1); - rb_define_method(rb_cAtomic, "get", ir_get, 0); - rb_define_method(rb_cAtomic, "set", ir_set, 1); - rb_define_method(rb_cAtomic, "get_and_set", ir_get_and_set, 1); - rb_define_method(rb_cAtomic, "_compare_and_set", ir_compare_and_set, 2); - rb_define_alias(rb_cAtomic, "value", "get"); - rb_define_alias(rb_cAtomic, "value=", "set"); - rb_define_alias(rb_cAtomic, "swap", "get_and_set"); + // CAtomicReference + rb_define_alloc_func(rb_cAtomicReference, ir_alloc); + rb_define_method(rb_cAtomicReference, "initialize", ir_initialize, -1); + rb_define_method(rb_cAtomicReference, "get", ir_get, 0); + rb_define_method(rb_cAtomicReference, "set", ir_set, 1); + rb_define_method(rb_cAtomicReference, "get_and_set", ir_get_and_set, 1); + rb_define_method(rb_cAtomicReference, "_compare_and_set", ir_compare_and_set, 2); + rb_define_alias(rb_cAtomicReference, "value", "get"); + rb_define_alias(rb_cAtomicReference, "value=", "set"); + rb_define_alias(rb_cAtomicReference, "swap", "get_and_set"); // CAtomicBoolean rb_define_alloc_func(rb_cAtomicBoolean, atomic_boolean_allocate); diff --git a/lib/concurrent.rb b/lib/concurrent.rb index 99c02f2ed..4acb31e29 100644 --- a/lib/concurrent.rb +++ b/lib/concurrent.rb @@ -13,10 +13,9 @@ require 'concurrent/executors' require 'concurrent/utilities' -require 'concurrent/atomic' +require 'concurrent/atomic/atomic_reference' require 'concurrent/agent' require 'concurrent/async' -require 'concurrent/atomic' require 'concurrent/dataflow' require 'concurrent/delay' require 'concurrent/exchanger' diff --git a/lib/concurrent/atomic.rb b/lib/concurrent/atomic.rb deleted file mode 100644 index 7cc0160a1..000000000 --- a/lib/concurrent/atomic.rb +++ /dev/null @@ -1,93 +0,0 @@ -##################################################################### -# Attempt to check for the deprecated ruby-atomic gem and warn the -# user that they should use the new implementation instead. - -if defined?(Atomic) - warn <<-TXT -[ATOMIC] Detected an `Atomic` class, which may indicate a dependency -on the ruby-atomic gem. That gem has been deprecated and merged into -the concurrent-ruby gem. Please use the Concurrent::Atomic class for -atomic references and not the Atomic class. - TXT -end -##################################################################### - -require 'concurrent/native_extensions' -require 'concurrent/utility/engine' -require 'concurrent/atomic_reference/concurrent_update_error' -require 'concurrent/atomic_reference/mutex_atomic' - -begin - # force fallback impl with FORCE_ATOMIC_FALLBACK=1 - if /[^0fF]/ =~ ENV['FORCE_ATOMIC_FALLBACK'] - ruby_engine = 'mutex_atomic' - else - ruby_engine = Concurrent.ruby_engine - end - - require "concurrent/atomic_reference/#{ruby_engine}" -rescue LoadError - #warn 'Compiled extensions not installed, pure Ruby Atomic will be used.' -end - -if defined? Concurrent::JavaAtomic - - # @!macro [attach] atomic_reference - # - # An object reference that may be updated atomically. - # - # Testing with ruby 2.1.2 - # - # *** Sequential updates *** - # user system total real - # no lock 0.000000 0.000000 0.000000 ( 0.005502) - # mutex 0.030000 0.000000 0.030000 ( 0.025158) - # MutexAtomic 0.100000 0.000000 0.100000 ( 0.103096) - # CAtomic 0.040000 0.000000 0.040000 ( 0.034012) - # - # *** Parallel updates *** - # user system total real - # no lock 0.010000 0.000000 0.010000 ( 0.009387) - # mutex 0.030000 0.010000 0.040000 ( 0.032545) - # MutexAtomic 0.830000 2.280000 3.110000 ( 2.146622) - # CAtomic 0.040000 0.000000 0.040000 ( 0.038332) - # - # Testing with jruby 1.9.3 - # - # *** Sequential updates *** - # user system total real - # no lock 0.170000 0.000000 0.170000 ( 0.051000) - # mutex 0.370000 0.010000 0.380000 ( 0.121000) - # MutexAtomic 1.530000 0.020000 1.550000 ( 0.471000) - # JavaAtomic 0.370000 0.010000 0.380000 ( 0.112000) - # - # *** Parallel updates *** - # user system total real - # no lock 0.390000 0.000000 0.390000 ( 0.105000) - # mutex 0.480000 0.040000 0.520000 ( 0.145000) - # MutexAtomic 1.600000 0.180000 1.780000 ( 0.511000) - # JavaAtomic 0.460000 0.010000 0.470000 ( 0.131000) - # - # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicReference.html - # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/package-summary.html - class Concurrent::Atomic < Concurrent::JavaAtomic - end - -elsif defined? Concurrent::RbxAtomic - - # @!macro atomic_reference - class Concurrent::Atomic < Concurrent::RbxAtomic - end - -elsif defined? Concurrent::CAtomic - - # @!macro atomic_reference - class Concurrent::Atomic < Concurrent::CAtomic - end - -else - - # @!macro atomic_reference - class Concurrent::Atomic < Concurrent::MutexAtomic - end -end diff --git a/lib/concurrent/atomic/atomic_reference.rb b/lib/concurrent/atomic/atomic_reference.rb new file mode 100644 index 000000000..6450d846b --- /dev/null +++ b/lib/concurrent/atomic/atomic_reference.rb @@ -0,0 +1,49 @@ +require 'concurrent/native_extensions' +require 'concurrent/utility/engine' +require 'concurrent/atomic_reference/concurrent_update_error' +require 'concurrent/atomic_reference/mutex_atomic' + +begin + # force fallback impl with FORCE_ATOMIC_FALLBACK=1 + if /[^0fF]/ =~ ENV['FORCE_ATOMIC_FALLBACK'] + ruby_engine = 'mutex_atomic' + else + ruby_engine = Concurrent.ruby_engine + end + + require "concurrent/atomic_reference/#{ruby_engine}" +rescue LoadError + #warn 'Compiled extensions not installed, pure Ruby Atomic will be used.' +end + +if defined? Concurrent::JavaAtomicReference + + # @!macro atomic_reference + class Concurrent::AtomicReference < Concurrent::JavaAtomicReference + end + +elsif defined? Concurrent::RbxAtomicReference + + # @!macro atomic_reference + class Concurrent::AtomicReference < Concurrent::RbxAtomicReference + end + +elsif defined? Concurrent::CAtomicReference + + # @!macro atomic_reference + class Concurrent::AtomicReference < Concurrent::CAtomicReference + end + +else + + # @!macro atomic_reference + class Concurrent::AtomicReference < Concurrent::MutexAtomicReference + end +end + +module Concurrent + + # @see Concurrent::AtomicReference + # @deprecated Use Concurrent::AtomicReference instead. + Atomic = AtomicReference +end diff --git a/lib/concurrent/atomic/read_write_lock.rb b/lib/concurrent/atomic/read_write_lock.rb index b60549471..a7fc388fa 100644 --- a/lib/concurrent/atomic/read_write_lock.rb +++ b/lib/concurrent/atomic/read_write_lock.rb @@ -1,5 +1,5 @@ require 'thread' -require 'concurrent/atomic' +require 'concurrent/atomic/atomic_reference' require 'concurrent/errors' module Concurrent @@ -53,11 +53,11 @@ class ReadWriteLock # Create a new `ReadWriteLock` in the unlocked state. def initialize - @counter = Atomic.new(0) # single integer which represents lock state - @reader_q = ConditionVariable.new # queue for waiting readers - @reader_mutex = Mutex.new # to protect reader queue - @writer_q = ConditionVariable.new # queue for waiting writers - @writer_mutex = Mutex.new # to protect writer queue + @counter = AtomicReference.new(0) # single integer which represents lock state + @reader_q = ConditionVariable.new # queue for waiting readers + @reader_mutex = Mutex.new # to protect reader queue + @writer_q = ConditionVariable.new # queue for waiting writers + @writer_mutex = Mutex.new # to protect writer queue end # Execute a block operation within a read lock. diff --git a/lib/concurrent/atomic/thread_local_var.rb b/lib/concurrent/atomic/thread_local_var.rb index 0ee96ccca..ecacfa27e 100644 --- a/lib/concurrent/atomic/thread_local_var.rb +++ b/lib/concurrent/atomic/thread_local_var.rb @@ -1,5 +1,3 @@ -require 'concurrent/atomic' - module Concurrent # @!macro [attach] abstract_thread_local_var diff --git a/lib/concurrent/atomic_reference/jruby.rb b/lib/concurrent/atomic_reference/jruby.rb index 2c3b6f135..c22cd34b2 100644 --- a/lib/concurrent/atomic_reference/jruby.rb +++ b/lib/concurrent/atomic_reference/jruby.rb @@ -1,12 +1,12 @@ require 'concurrent/native_extensions' -if defined?(Concurrent::JavaAtomic) +if defined?(Concurrent::JavaAtomicReference) require 'concurrent/atomic_reference/direct_update' module Concurrent # @!macro atomic_reference - class JavaAtomic + class JavaAtomicReference include Concurrent::AtomicDirectUpdate end end diff --git a/lib/concurrent/atomic_reference/mutex_atomic.rb b/lib/concurrent/atomic_reference/mutex_atomic.rb index 20a513579..c488911ae 100644 --- a/lib/concurrent/atomic_reference/mutex_atomic.rb +++ b/lib/concurrent/atomic_reference/mutex_atomic.rb @@ -5,7 +5,7 @@ module Concurrent # @!macro atomic_reference - class MutexAtomic + class MutexAtomicReference include Concurrent::AtomicDirectUpdate include Concurrent::AtomicNumericCompareAndSetWrapper diff --git a/lib/concurrent/atomic_reference/rbx.rb b/lib/concurrent/atomic_reference/rbx.rb index f9607a5ad..94df637df 100644 --- a/lib/concurrent/atomic_reference/rbx.rb +++ b/lib/concurrent/atomic_reference/rbx.rb @@ -7,7 +7,7 @@ module Concurrent # # @note Extends `Rubinius::AtomicReference` version adding aliases # and numeric logic. - class RbxAtomic < Rubinius::AtomicReference + class RbxAtomicReference < Rubinius::AtomicReference alias _compare_and_set compare_and_set include Concurrent::AtomicDirectUpdate include Concurrent::AtomicNumericCompareAndSetWrapper diff --git a/lib/concurrent/atomic_reference/ruby.rb b/lib/concurrent/atomic_reference/ruby.rb index 6a3be3b0c..14c51a188 100644 --- a/lib/concurrent/atomic_reference/ruby.rb +++ b/lib/concurrent/atomic_reference/ruby.rb @@ -1,4 +1,4 @@ -if defined? Concurrent::CAtomic +if defined? Concurrent::CAtomicReference require 'concurrent/native_extensions' require 'concurrent/atomic_reference/direct_update' require 'concurrent/atomic_reference/numeric_cas_wrapper' @@ -6,7 +6,7 @@ module Concurrent # @!macro atomic_reference - class CAtomic + class CAtomicReference include Concurrent::AtomicDirectUpdate include Concurrent::AtomicNumericCompareAndSetWrapper diff --git a/lib/concurrent/atomics.rb b/lib/concurrent/atomics.rb index 1b2af04a0..50e327c29 100644 --- a/lib/concurrent/atomics.rb +++ b/lib/concurrent/atomics.rb @@ -1,4 +1,43 @@ -require 'concurrent/atomic' +# @!macro [new] atomic_reference +# +# An object reference that may be updated atomically. +# +# Testing with ruby 2.1.2 +# +# *** Sequential updates *** +# user system total real +# no lock 0.000000 0.000000 0.000000 ( 0.005502) +# mutex 0.030000 0.000000 0.030000 ( 0.025158) +# MutexAtomicReference 0.100000 0.000000 0.100000 ( 0.103096) +# CAtomicReference 0.040000 0.000000 0.040000 ( 0.034012) +# +# *** Parallel updates *** +# user system total real +# no lock 0.010000 0.000000 0.010000 ( 0.009387) +# mutex 0.030000 0.010000 0.040000 ( 0.032545) +# MutexAtomicReference 0.830000 2.280000 3.110000 ( 2.146622) +# CAtomicReference 0.040000 0.000000 0.040000 ( 0.038332) +# +# Testing with jruby 1.9.3 +# +# *** Sequential updates *** +# user system total real +# no lock 0.170000 0.000000 0.170000 ( 0.051000) +# mutex 0.370000 0.010000 0.380000 ( 0.121000) +# MutexAtomicReference 1.530000 0.020000 1.550000 ( 0.471000) +# JavaAtomicReference 0.370000 0.010000 0.380000 ( 0.112000) +# +# *** Parallel updates *** +# user system total real +# no lock 0.390000 0.000000 0.390000 ( 0.105000) +# mutex 0.480000 0.040000 0.520000 ( 0.145000) +# MutexAtomicReference 1.600000 0.180000 1.780000 ( 0.511000) +# JavaAtomicReference 0.460000 0.010000 0.470000 ( 0.131000) +# +# @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicReference.html +# @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/package-summary.html + +require 'concurrent/atomic/atomic_reference' require 'concurrent/atomic/atomic_boolean' require 'concurrent/atomic/atomic_fixnum' require 'concurrent/atomic/condition' diff --git a/lib/concurrent/configuration.rb b/lib/concurrent/configuration.rb index e7e9d7b05..ce2d58c7f 100644 --- a/lib/concurrent/configuration.rb +++ b/lib/concurrent/configuration.rb @@ -13,7 +13,7 @@ module Concurrent private_constant :NULL_LOGGER # @!visibility private - GLOBAL_LOGGER = Atomic.new(NULL_LOGGER) + GLOBAL_LOGGER = AtomicReference.new(NULL_LOGGER) private_constant :GLOBAL_LOGGER # @!visibility private @@ -219,7 +219,7 @@ def auto_terminate end # create the default configuration on load - CONFIGURATION = Atomic.new(Configuration.new) + CONFIGURATION = AtomicReference.new(Configuration.new) private_constant :CONFIGURATION # @return [Configuration] diff --git a/lib/concurrent/lazy_register.rb b/lib/concurrent/lazy_register.rb index d862379af..0e4b837c0 100644 --- a/lib/concurrent/lazy_register.rb +++ b/lib/concurrent/lazy_register.rb @@ -1,4 +1,4 @@ -require 'concurrent/atomic' +require 'concurrent/atomic/atomic_reference' require 'concurrent/delay' module Concurrent @@ -7,17 +7,17 @@ module Concurrent # # @example # register = Concurrent::LazyRegister.new - # #=> #> + # #=> #> # register[:key] # #=> nil # register.add(:key) { Concurrent::Actor.spawn!(Actor::AdHoc, :ping) { -> message { message } } } - # #=> #> + # #=> #> # register[:key] # #=> # class LazyRegister def initialize - @data = Atomic.new Hash.new + @data = AtomicReference.new(Hash.new) end # Element reference. Retrieves the value object corresponding to the diff --git a/spec/concurrent/atomic_spec.rb b/spec/concurrent/atomic/atomic_reference_spec.rb similarity index 63% rename from spec/concurrent/atomic_spec.rb rename to spec/concurrent/atomic/atomic_reference_spec.rb index cb23c0106..b50295124 100644 --- a/spec/concurrent/atomic_spec.rb +++ b/spec/concurrent/atomic/atomic_reference_spec.rb @@ -1,4 +1,4 @@ -shared_examples :atomic do +shared_examples :atomic_reference do specify :test_construct do atomic = described_class.new @@ -127,44 +127,82 @@ module Concurrent - describe Atomic do - it_should_behave_like :atomic + describe AtomicReference do + it_should_behave_like :atomic_reference end - describe MutexAtomic do - it_should_behave_like :atomic + describe MutexAtomicReference do + it_should_behave_like :atomic_reference end - if defined? Concurrent::CAtomic - describe CAtomic do - it_should_behave_like :atomic + if defined? Concurrent::CAtomicReference + describe CAtomicReference do + it_should_behave_like :atomic_reference end - elsif defined? Concurrent::JavaAtomic - describe JavaAtomic do - it_should_behave_like :atomic + elsif defined? Concurrent::JavaAtomicReference + describe JavaAtomicReference do + it_should_behave_like :atomic_reference end - elsif defined? Concurrent::RbxAtomic - describe RbxAtomic do - it_should_behave_like :atomic + elsif defined? Concurrent::RbxAtomicReference + describe RbxAtomicReference do + it_should_behave_like :atomic_reference end end - describe Atomic do + describe AtomicReference do if Concurrent.on_jruby? - it 'inherits from JavaAtomic' do - expect(Atomic.ancestors).to include(Concurrent::JavaAtomic) + it 'inherits from JavaAtomicReference' do + expect(AtomicReference.ancestors).to include(Concurrent::JavaAtomicReference) end elsif Concurrent.allow_c_extensions? - it 'inherits from CAtomic' do - expect(Atomic.ancestors).to include(Concurrent::CAtomic) + it 'inherits from CAtomicReference' do + expect(AtomicReference.ancestors).to include(Concurrent::CAtomicReference) end elsif Concurrent.on_rbx? - it 'inherits from RbxAtomic' do - expect(Atomic.ancestors).to include(Concurrent::RbxAtomic) + it 'inherits from RbxAtomicReference' do + expect(AtomicReference.ancestors).to include(Concurrent::RbxAtomicReference) end else - it 'inherits from MutexAtomic' do - expect(Atomic.ancestors).to include(Concurrent::MutexAtomic) + it 'inherits from MutexAtomicReference' do + expect(AtomicReference.ancestors).to include(Concurrent::MutexAtomicReference) + end + end + end + + describe MutexAtomicReference do + it_should_behave_like :atomic_reference + end + + if defined? Concurrent::CAtomicReference + describe CAtomicReference do + it_should_behave_like :atomic_reference + end + elsif defined? Concurrent::JavaAtomicReference + describe JavaAtomicReference do + it_should_behave_like :atomic_reference + end + elsif defined? Concurrent::RbxAtomicReference + describe RbxAtomicReference do + it_should_behave_like :atomic_reference + end + end + + describe AtomicReference do + if Concurrent.on_jruby? + it 'inherits from JavaAtomicReference' do + expect(AtomicReference.ancestors).to include(Concurrent::JavaAtomicReference) + end + elsif Concurrent.allow_c_extensions? + it 'inherits from CAtomicReference' do + expect(AtomicReference.ancestors).to include(Concurrent::CAtomicReference) + end + elsif Concurrent.on_rbx? + it 'inherits from RbxAtomicReference' do + expect(AtomicReference.ancestors).to include(Concurrent::RbxAtomicReference) + end + else + it 'inherits from MutexAtomicReference' do + expect(AtomicReference.ancestors).to include(Concurrent::MutexAtomicReference) end end end diff --git a/spec/concurrent/atomic/read_write_lock_spec.rb b/spec/concurrent/atomic/read_write_lock_spec.rb index db073775c..1f4f449bf 100644 --- a/spec/concurrent/atomic/read_write_lock_spec.rb +++ b/spec/concurrent/atomic/read_write_lock_spec.rb @@ -142,8 +142,8 @@ module Concurrent end it 'raises an exception if maximum lock limit is exceeded' do - counter = Concurrent::Atomic.new(ReadWriteLock::MAX_READERS) - allow(Concurrent::Atomic).to receive(:new).with(anything).and_return(counter) + counter = Concurrent::AtomicReference.new(ReadWriteLock::MAX_READERS) + allow(Concurrent::AtomicReference).to receive(:new).with(anything).and_return(counter) expect { subject.with_read_lock { nil } }.to raise_error(Concurrent::ResourceLimitError) @@ -182,8 +182,8 @@ module Concurrent end it 'raises an exception if maximum lock limit is exceeded' do - counter = Concurrent::Atomic.new(ReadWriteLock::MAX_WRITERS) - allow(Concurrent::Atomic).to receive(:new).with(anything).and_return(counter) + counter = Concurrent::AtomicReference.new(ReadWriteLock::MAX_WRITERS) + allow(Concurrent::AtomicReference).to receive(:new).with(anything).and_return(counter) expect { subject.with_write_lock { nil } }.to raise_error(Concurrent::ResourceLimitError) @@ -200,8 +200,8 @@ module Concurrent context '#acquire_read_lock' do it 'increments the lock count' do - counter = Concurrent::Atomic.new(0) - allow(Concurrent::Atomic).to receive(:new).with(anything).and_return(counter) + counter = Concurrent::AtomicReference.new(0) + allow(Concurrent::AtomicReference).to receive(:new).with(anything).and_return(counter) subject.acquire_read_lock expect(counter.value).to eq 1 end @@ -241,8 +241,8 @@ module Concurrent end it 'does not wait for any running readers' do - counter = Concurrent::Atomic.new(0) - allow(Concurrent::Atomic).to receive(:new).with(anything).and_return(counter) + counter = Concurrent::AtomicReference.new(0) + allow(Concurrent::AtomicReference).to receive(:new).with(anything).and_return(counter) latch_1 = Concurrent::CountDownLatch.new(1) latch_2 = Concurrent::CountDownLatch.new(1) @@ -280,8 +280,8 @@ module Concurrent end it 'raises an exception if maximum lock limit is exceeded' do - counter = Concurrent::Atomic.new(ReadWriteLock::MAX_WRITERS) - allow(Concurrent::Atomic).to receive(:new).with(anything).and_return(counter) + counter = Concurrent::AtomicReference.new(ReadWriteLock::MAX_WRITERS) + allow(Concurrent::AtomicReference).to receive(:new).with(anything).and_return(counter) expect { subject.acquire_write_lock { nil } }.to raise_error(Concurrent::ResourceLimitError) @@ -295,8 +295,8 @@ module Concurrent context '#release_read_lock' do it 'decrements the counter' do - counter = Concurrent::Atomic.new(0) - allow(Concurrent::Atomic).to receive(:new).with(anything).and_return(counter) + counter = Concurrent::AtomicReference.new(0) + allow(Concurrent::AtomicReference).to receive(:new).with(anything).and_return(counter) subject.acquire_read_lock expect(counter.value).to eq 1 subject.release_read_lock @@ -338,8 +338,8 @@ module Concurrent context '#acquire_write_lock' do it 'increments the lock count' do - counter = Concurrent::Atomic.new(0) - allow(Concurrent::Atomic).to receive(:new).with(anything).and_return(counter) + counter = Concurrent::AtomicReference.new(0) + allow(Concurrent::AtomicReference).to receive(:new).with(anything).and_return(counter) subject.acquire_write_lock expect(counter.value).to be > 1 end @@ -413,8 +413,8 @@ module Concurrent end it 'raises an exception if maximum lock limit is exceeded' do - counter = Concurrent::Atomic.new(ReadWriteLock::MAX_WRITERS) - allow(Concurrent::Atomic).to receive(:new).with(anything).and_return(counter) + counter = Concurrent::AtomicReference.new(ReadWriteLock::MAX_WRITERS) + allow(Concurrent::AtomicReference).to receive(:new).with(anything).and_return(counter) expect { subject.acquire_write_lock { nil } }.to raise_error(Concurrent::ResourceLimitError) @@ -428,8 +428,8 @@ module Concurrent context '#release_write_lock' do it 'decrements the counter' do - counter = Concurrent::Atomic.new(0) - allow(Concurrent::Atomic).to receive(:new).with(anything).and_return(counter) + counter = Concurrent::AtomicReference.new(0) + allow(Concurrent::AtomicReference).to receive(:new).with(anything).and_return(counter) subject.acquire_write_lock expect(counter.value).to be > 1 subject.release_write_lock