Bump concurrent-ruby from 1.3.6 to 1.3.7#1006
Open
dependabot[bot] wants to merge 1 commit into
Open
Conversation
Bumps [concurrent-ruby](https://github.com/ruby-concurrency/concurrent-ruby) from 1.3.6 to 1.3.7. - [Release notes](https://github.com/ruby-concurrency/concurrent-ruby/releases) - [Changelog](https://github.com/ruby-concurrency/concurrent-ruby/blob/master/CHANGELOG.md) - [Commits](ruby-concurrency/concurrent-ruby@v1.3.6...v1.3.7) --- updated-dependencies: - dependency-name: concurrent-ruby dependency-version: 1.3.7 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>
Contributor
4 similar comments
Contributor
Contributor
Contributor
Contributor
Contributor
gem compare concurrent-ruby 1.3.6 1.3.7Compared versions: ["1.3.6", "1.3.7"]
DIFFERENT date:
1.3.6: 2025-12-13 00:00:00 UTC
1.3.7: 2026-06-16 00:00:00 UTC
DIFFERENT rubygems_version:
1.3.6: 3.3.27
1.3.7: 4.0.6
DIFFERENT version:
1.3.6: 1.3.6
1.3.7: 1.3.7
DIFFERENT files:
1.3.6->1.3.7:
* Changed:
CHANGELOG.md +6/-0
Rakefile +2/-3
ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java +3/-38
lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb +9/-2
lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb +15/-2
lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb +8/-1
lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb +1/-2
lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb +9/-1
lib/concurrent-ruby/concurrent/version.rb +1/-1
DIFFERENT extra_rdoc_files:
1.3.6->1.3.7:
* Changed:
CHANGELOG.md +6/-0 |
3 similar comments
Contributor
gem compare concurrent-ruby 1.3.6 1.3.7Compared versions: ["1.3.6", "1.3.7"]
DIFFERENT date:
1.3.6: 2025-12-13 00:00:00 UTC
1.3.7: 2026-06-16 00:00:00 UTC
DIFFERENT rubygems_version:
1.3.6: 3.3.27
1.3.7: 4.0.6
DIFFERENT version:
1.3.6: 1.3.6
1.3.7: 1.3.7
DIFFERENT files:
1.3.6->1.3.7:
* Changed:
CHANGELOG.md +6/-0
Rakefile +2/-3
ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java +3/-38
lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb +9/-2
lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb +15/-2
lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb +8/-1
lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb +1/-2
lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb +9/-1
lib/concurrent-ruby/concurrent/version.rb +1/-1
DIFFERENT extra_rdoc_files:
1.3.6->1.3.7:
* Changed:
CHANGELOG.md +6/-0 |
Contributor
gem compare concurrent-ruby 1.3.6 1.3.7Compared versions: ["1.3.6", "1.3.7"]
DIFFERENT date:
1.3.6: 2025-12-13 00:00:00 UTC
1.3.7: 2026-06-16 00:00:00 UTC
DIFFERENT rubygems_version:
1.3.6: 3.3.27
1.3.7: 4.0.6
DIFFERENT version:
1.3.6: 1.3.6
1.3.7: 1.3.7
DIFFERENT files:
1.3.6->1.3.7:
* Changed:
CHANGELOG.md +6/-0
Rakefile +2/-3
ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java +3/-38
lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb +9/-2
lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb +15/-2
lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb +8/-1
lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb +1/-2
lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb +9/-1
lib/concurrent-ruby/concurrent/version.rb +1/-1
DIFFERENT extra_rdoc_files:
1.3.6->1.3.7:
* Changed:
CHANGELOG.md +6/-0 |
Contributor
gem compare concurrent-ruby 1.3.6 1.3.7Compared versions: ["1.3.6", "1.3.7"]
DIFFERENT date:
1.3.6: 2025-12-13 00:00:00 UTC
1.3.7: 2026-06-16 00:00:00 UTC
DIFFERENT rubygems_version:
1.3.6: 3.3.27
1.3.7: 4.0.6
DIFFERENT version:
1.3.6: 1.3.6
1.3.7: 1.3.7
DIFFERENT files:
1.3.6->1.3.7:
* Changed:
CHANGELOG.md +6/-0
Rakefile +2/-3
ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java +3/-38
lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb +9/-2
lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb +15/-2
lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb +8/-1
lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb +1/-2
lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb +9/-1
lib/concurrent-ruby/concurrent/version.rb +1/-1
DIFFERENT extra_rdoc_files:
1.3.6->1.3.7:
* Changed:
CHANGELOG.md +6/-0 |
Contributor
gem compare --diff concurrent-ruby 1.3.6 1.3.7Compared versions: ["1.3.6", "1.3.7"]
DIFFERENT files:
1.3.6->1.3.7:
* Changed:
CHANGELOG.md
--- /tmp/d20260623-881-xhnwva/concurrent-ruby-1.3.6/CHANGELOG.md 2026-06-23 23:37:39.490051124 +0000
+++ /tmp/d20260623-881-xhnwva/concurrent-ruby-1.3.7/CHANGELOG.md 2026-06-23 23:37:39.507051255 +0000
@@ -2,0 +3,6 @@
+## Release v1.3.7 (16 June 2026)
+
+concurrent-ruby:
+
+* See the [release notes on GitHub](https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.3.7).
+
Rakefile
--- /tmp/d20260623-881-xhnwva/concurrent-ruby-1.3.6/Rakefile 2026-06-23 23:37:39.490051124 +0000
+++ /tmp/d20260623-881-xhnwva/concurrent-ruby-1.3.7/Rakefile 2026-06-23 23:37:39.508051263 +0000
@@ -338,3 +338,2 @@
- # TODO: (petr 05-Jun-2021) automate and renew the process
- puts 'Manually: create a release on GitHub with relevant changelog part'
- puts 'Manually: send email same as release with relevant changelog part'
+ puts
+ puts 'Manually: create a release on GitHub, use the "Generate release notes" button'
ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java
--- /tmp/d20260623-881-xhnwva/concurrent-ruby-1.3.6/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java 2026-06-23 23:37:39.491051132 +0000
+++ /tmp/d20260623-881-xhnwva/concurrent-ruby-1.3.7/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java 2026-06-23 23:37:39.508051263 +0000
@@ -2,0 +3,2 @@
+import static org.jruby.runtime.Visibility.PRIVATE;
+
@@ -5 +6,0 @@
-import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
@@ -9 +9,0 @@
-import org.jruby.RubyNumeric;
@@ -94 +94 @@
- @JRubyMethod(name = {"compare_and_set", "compare_and_swap"})
+ @JRubyMethod(name = "_compare_and_set", visibility = PRIVATE)
@@ -97,6 +96,0 @@
-
- if (expectedValue instanceof RubyNumeric) {
- // numerics are not always idempotent in Ruby, so we need to do slower logic
- return compareAndSetNumeric(context, expectedValue, newValue);
- }
-
@@ -113,29 +106,0 @@
- }
- }
- }
-
- private IRubyObject compareAndSetNumeric(ThreadContext context, IRubyObject expectedValue, IRubyObject newValue) {
- Ruby runtime = context.runtime;
-
- // loop until:
- // * reference CAS would succeed for same-valued objects
- // * current and expected have different values as determined by #equals
- while (true) {
- IRubyObject current = reference;
-
- if (!(current instanceof RubyNumeric)) {
- // old value is not numeric, CAS fails
- return runtime.getFalse();
- }
-
- RubyNumeric currentNumber = (RubyNumeric)current;
- if (!currentNumber.equals(expectedValue)) {
- // current number does not equal expected, fail CAS
- return runtime.getFalse();
- }
-
- // check that current has not changed, or else allow loop to repeat
- boolean success = UNSAFE.compareAndSwapObject(this, referenceOffset, current, newValue);
- if (success) {
- // value is same and did not change in interim...success
- return runtime.getTrue();
lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb
--- /tmp/d20260623-881-xhnwva/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb 2026-06-23 23:37:39.496051171 +0000
+++ /tmp/d20260623-881-xhnwva/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb 2026-06-23 23:37:39.512051294 +0000
@@ -25 +24,0 @@
- alias_method :compare_and_swap, :compare_and_set
@@ -32,0 +32 @@
+ include AtomicNumericCompareAndSetWrapper
@@ -37,0 +38,8 @@
+ if private_method_defined?(:compare_and_set_reference)
+ alias_method :_compare_and_set, :compare_and_set_reference
+ private :_compare_and_set
+ include AtomicNumericCompareAndSetWrapper
+ else
+ # AtomicNumericCompareAndSetWrapper behavior already in TruffleRuby::AtomicReference
+ alias_method :compare_and_swap, :compare_and_set
+ end
@@ -40 +47,0 @@
- alias_method :compare_and_swap, :compare_and_set
lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb
--- /tmp/d20260623-881-xhnwva/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb 2026-06-23 23:37:39.497051178 +0000
+++ /tmp/d20260623-881-xhnwva/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb 2026-06-23 23:37:39.513051302 +0000
@@ -2,0 +3 @@
+require 'concurrent/atomic/atomic_reference'
@@ -61 +62,2 @@
- @Counter = AtomicFixnum.new(0) # single integer which represents lock state
+ @Counter = AtomicFixnum.new(0) # single integer which represents lock state
+ @Writer = AtomicReference.new(nil) # the thread currently holding the write lock
@@ -139,0 +142,2 @@
+ #
+ # @raise [Concurrent::IllegalOperationError] if no read lock is currently held.
@@ -142,0 +147,2 @@
+ raise IllegalOperationError, 'Cannot release a read lock which is not held' if running_readers(c) == 0
+
@@ -189,0 +196 @@
+ @Writer.set(Thread.current)
@@ -195,0 +203,3 @@
+ #
+ # @raise [Concurrent::IllegalOperationError] if the write lock is not held
+ # by the current thread.
@@ -197 +207,4 @@
- return true unless running_writer?
+ unless @Writer.compare_and_set(Thread.current, nil)
+ raise IllegalOperationError, 'Cannot release a write lock which is not held by the current thread'
+ end
+
lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb
--- /tmp/d20260623-881-xhnwva/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb 2026-06-23 23:37:39.497051178 +0000
+++ /tmp/d20260623-881-xhnwva/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb 2026-06-23 23:37:39.514051309 +0000
@@ -161 +161 @@
- # is exceeded.
+ # or per-thread reentrant acquires is exceeded.
@@ -163,0 +164,2 @@
+ raise ResourceLimitError.new('Too many reader holds on this thread') if (held & READ_LOCK_MASK) == READ_LOCK_MASK
+
@@ -214,0 +217,3 @@
+ #
+ # @raise [Concurrent::ResourceLimitError] if the maximum number of per-thread
+ # reentrant acquires is exceeded.
@@ -216,0 +222,2 @@
+ raise ResourceLimitError.new('Too many reader holds on this thread') if (held & READ_LOCK_MASK) == READ_LOCK_MASK
+
lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb
--- /tmp/d20260623-881-xhnwva/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb 2026-06-23 23:37:39.497051178 +0000
+++ /tmp/d20260623-881-xhnwva/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb 2026-06-23 23:37:39.514051309 +0000
@@ -13 +12,0 @@
- alias_method :compare_and_swap, :compare_and_set
@@ -45 +44 @@
- def _compare_and_set(old_value, new_value)
+ private def _compare_and_set(old_value, new_value)
lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb
--- /tmp/d20260623-881-xhnwva/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb 2026-06-23 23:37:39.497051178 +0000
+++ /tmp/d20260623-881-xhnwva/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb 2026-06-23 23:37:39.514051309 +0000
@@ -11,0 +12,2 @@
+ # NaN is never == to itself; match it explicitly so #update can terminate.
+ expected_nan = old_value.respond_to?(:nan?) && old_value.nan?
@@ -17 +19,5 @@
- return false unless old == old_value
+ if expected_nan
+ return false unless old.respond_to?(:nan?) && old.nan?
+ else
+ return false unless old == old_value
+ end
@@ -25,0 +32,2 @@
+
+ alias_method :compare_and_swap, :compare_and_set
lib/concurrent-ruby/concurrent/concurrent_ruby.jar
Binary files /tmp/d20260623-881-xhnwva/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/concurrent_ruby.jar and /tmp/d20260623-881-xhnwva/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/concurrent_ruby.jar differ
lib/concurrent-ruby/concurrent/version.rb
--- /tmp/d20260623-881-xhnwva/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/version.rb 2026-06-23 23:37:39.507051255 +0000
+++ /tmp/d20260623-881-xhnwva/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/version.rb 2026-06-23 23:37:39.525051394 +0000
@@ -2 +2 @@
- VERSION = '1.3.6'
+ VERSION = '1.3.7' |
Contributor
gem compare --diff concurrent-ruby 1.3.6 1.3.7Compared versions: ["1.3.6", "1.3.7"]
DIFFERENT files:
1.3.6->1.3.7:
* Changed:
CHANGELOG.md
--- /tmp/d20260623-1016-tevtmy/concurrent-ruby-1.3.6/CHANGELOG.md 2026-06-23 23:37:44.832679303 +0000
+++ /tmp/d20260623-1016-tevtmy/concurrent-ruby-1.3.7/CHANGELOG.md 2026-06-23 23:37:44.850679474 +0000
@@ -2,0 +3,6 @@
+## Release v1.3.7 (16 June 2026)
+
+concurrent-ruby:
+
+* See the [release notes on GitHub](https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.3.7).
+
Rakefile
--- /tmp/d20260623-1016-tevtmy/concurrent-ruby-1.3.6/Rakefile 2026-06-23 23:37:44.832679303 +0000
+++ /tmp/d20260623-1016-tevtmy/concurrent-ruby-1.3.7/Rakefile 2026-06-23 23:37:44.850679474 +0000
@@ -338,3 +338,2 @@
- # TODO: (petr 05-Jun-2021) automate and renew the process
- puts 'Manually: create a release on GitHub with relevant changelog part'
- puts 'Manually: send email same as release with relevant changelog part'
+ puts
+ puts 'Manually: create a release on GitHub, use the "Generate release notes" button'
ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java
--- /tmp/d20260623-1016-tevtmy/concurrent-ruby-1.3.6/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java 2026-06-23 23:37:44.833679313 +0000
+++ /tmp/d20260623-1016-tevtmy/concurrent-ruby-1.3.7/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java 2026-06-23 23:37:44.850679474 +0000
@@ -2,0 +3,2 @@
+import static org.jruby.runtime.Visibility.PRIVATE;
+
@@ -5 +6,0 @@
-import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
@@ -9 +9,0 @@
-import org.jruby.RubyNumeric;
@@ -94 +94 @@
- @JRubyMethod(name = {"compare_and_set", "compare_and_swap"})
+ @JRubyMethod(name = "_compare_and_set", visibility = PRIVATE)
@@ -97,6 +96,0 @@
-
- if (expectedValue instanceof RubyNumeric) {
- // numerics are not always idempotent in Ruby, so we need to do slower logic
- return compareAndSetNumeric(context, expectedValue, newValue);
- }
-
@@ -113,29 +106,0 @@
- }
- }
- }
-
- private IRubyObject compareAndSetNumeric(ThreadContext context, IRubyObject expectedValue, IRubyObject newValue) {
- Ruby runtime = context.runtime;
-
- // loop until:
- // * reference CAS would succeed for same-valued objects
- // * current and expected have different values as determined by #equals
- while (true) {
- IRubyObject current = reference;
-
- if (!(current instanceof RubyNumeric)) {
- // old value is not numeric, CAS fails
- return runtime.getFalse();
- }
-
- RubyNumeric currentNumber = (RubyNumeric)current;
- if (!currentNumber.equals(expectedValue)) {
- // current number does not equal expected, fail CAS
- return runtime.getFalse();
- }
-
- // check that current has not changed, or else allow loop to repeat
- boolean success = UNSAFE.compareAndSwapObject(this, referenceOffset, current, newValue);
- if (success) {
- // value is same and did not change in interim...success
- return runtime.getTrue();
lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb
--- /tmp/d20260623-1016-tevtmy/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb 2026-06-23 23:37:44.838679360 +0000
+++ /tmp/d20260623-1016-tevtmy/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb 2026-06-23 23:37:44.855679522 +0000
@@ -25 +24,0 @@
- alias_method :compare_and_swap, :compare_and_set
@@ -32,0 +32 @@
+ include AtomicNumericCompareAndSetWrapper
@@ -37,0 +38,8 @@
+ if private_method_defined?(:compare_and_set_reference)
+ alias_method :_compare_and_set, :compare_and_set_reference
+ private :_compare_and_set
+ include AtomicNumericCompareAndSetWrapper
+ else
+ # AtomicNumericCompareAndSetWrapper behavior already in TruffleRuby::AtomicReference
+ alias_method :compare_and_swap, :compare_and_set
+ end
@@ -40 +47,0 @@
- alias_method :compare_and_swap, :compare_and_set
lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb
--- /tmp/d20260623-1016-tevtmy/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb 2026-06-23 23:37:44.839679370 +0000
+++ /tmp/d20260623-1016-tevtmy/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb 2026-06-23 23:37:44.856679531 +0000
@@ -2,0 +3 @@
+require 'concurrent/atomic/atomic_reference'
@@ -61 +62,2 @@
- @Counter = AtomicFixnum.new(0) # single integer which represents lock state
+ @Counter = AtomicFixnum.new(0) # single integer which represents lock state
+ @Writer = AtomicReference.new(nil) # the thread currently holding the write lock
@@ -139,0 +142,2 @@
+ #
+ # @raise [Concurrent::IllegalOperationError] if no read lock is currently held.
@@ -142,0 +147,2 @@
+ raise IllegalOperationError, 'Cannot release a read lock which is not held' if running_readers(c) == 0
+
@@ -189,0 +196 @@
+ @Writer.set(Thread.current)
@@ -195,0 +203,3 @@
+ #
+ # @raise [Concurrent::IllegalOperationError] if the write lock is not held
+ # by the current thread.
@@ -197 +207,4 @@
- return true unless running_writer?
+ unless @Writer.compare_and_set(Thread.current, nil)
+ raise IllegalOperationError, 'Cannot release a write lock which is not held by the current thread'
+ end
+
lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb
--- /tmp/d20260623-1016-tevtmy/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb 2026-06-23 23:37:44.839679370 +0000
+++ /tmp/d20260623-1016-tevtmy/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb 2026-06-23 23:37:44.856679531 +0000
@@ -161 +161 @@
- # is exceeded.
+ # or per-thread reentrant acquires is exceeded.
@@ -163,0 +164,2 @@
+ raise ResourceLimitError.new('Too many reader holds on this thread') if (held & READ_LOCK_MASK) == READ_LOCK_MASK
+
@@ -214,0 +217,3 @@
+ #
+ # @raise [Concurrent::ResourceLimitError] if the maximum number of per-thread
+ # reentrant acquires is exceeded.
@@ -216,0 +222,2 @@
+ raise ResourceLimitError.new('Too many reader holds on this thread') if (held & READ_LOCK_MASK) == READ_LOCK_MASK
+
lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb
--- /tmp/d20260623-1016-tevtmy/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb 2026-06-23 23:37:44.840679379 +0000
+++ /tmp/d20260623-1016-tevtmy/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb 2026-06-23 23:37:44.856679531 +0000
@@ -13 +12,0 @@
- alias_method :compare_and_swap, :compare_and_set
@@ -45 +44 @@
- def _compare_and_set(old_value, new_value)
+ private def _compare_and_set(old_value, new_value)
lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb
--- /tmp/d20260623-1016-tevtmy/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb 2026-06-23 23:37:44.840679379 +0000
+++ /tmp/d20260623-1016-tevtmy/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb 2026-06-23 23:37:44.856679531 +0000
@@ -11,0 +12,2 @@
+ # NaN is never == to itself; match it explicitly so #update can terminate.
+ expected_nan = old_value.respond_to?(:nan?) && old_value.nan?
@@ -17 +19,5 @@
- return false unless old == old_value
+ if expected_nan
+ return false unless old.respond_to?(:nan?) && old.nan?
+ else
+ return false unless old == old_value
+ end
@@ -25,0 +32,2 @@
+
+ alias_method :compare_and_swap, :compare_and_set
lib/concurrent-ruby/concurrent/concurrent_ruby.jar
Binary files /tmp/d20260623-1016-tevtmy/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/concurrent_ruby.jar and /tmp/d20260623-1016-tevtmy/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/concurrent_ruby.jar differ
lib/concurrent-ruby/concurrent/version.rb
--- /tmp/d20260623-1016-tevtmy/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/version.rb 2026-06-23 23:37:44.849679465 +0000
+++ /tmp/d20260623-1016-tevtmy/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/version.rb 2026-06-23 23:37:44.866679626 +0000
@@ -2 +2 @@
- VERSION = '1.3.6'
+ VERSION = '1.3.7' |
Contributor
gem compare concurrent-ruby 1.3.6 1.3.7Compared versions: ["1.3.6", "1.3.7"]
DIFFERENT date:
1.3.6: 2025-12-13 00:00:00 UTC
1.3.7: 2026-06-16 00:00:00 UTC
DIFFERENT rubygems_version:
1.3.6: 3.3.27
1.3.7: 4.0.6
DIFFERENT version:
1.3.6: 1.3.6
1.3.7: 1.3.7
DIFFERENT files:
1.3.6->1.3.7:
* Changed:
CHANGELOG.md +6/-0
Rakefile +2/-3
ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java +3/-38
lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb +9/-2
lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb +15/-2
lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb +8/-1
lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb +1/-2
lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb +9/-1
lib/concurrent-ruby/concurrent/version.rb +1/-1
DIFFERENT extra_rdoc_files:
1.3.6->1.3.7:
* Changed:
CHANGELOG.md +6/-0 |
Contributor
gem compare --diff concurrent-ruby 1.3.6 1.3.7Compared versions: ["1.3.6", "1.3.7"]
DIFFERENT files:
1.3.6->1.3.7:
* Changed:
CHANGELOG.md
--- /tmp/d20260623-888-cy4lhc/concurrent-ruby-1.3.6/CHANGELOG.md 2026-06-23 23:38:02.580830569 +0000
+++ /tmp/d20260623-888-cy4lhc/concurrent-ruby-1.3.7/CHANGELOG.md 2026-06-23 23:38:02.598830517 +0000
@@ -2,0 +3,6 @@
+## Release v1.3.7 (16 June 2026)
+
+concurrent-ruby:
+
+* See the [release notes on GitHub](https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.3.7).
+
Rakefile
--- /tmp/d20260623-888-cy4lhc/concurrent-ruby-1.3.6/Rakefile 2026-06-23 23:38:02.581830566 +0000
+++ /tmp/d20260623-888-cy4lhc/concurrent-ruby-1.3.7/Rakefile 2026-06-23 23:38:02.599830514 +0000
@@ -338,3 +338,2 @@
- # TODO: (petr 05-Jun-2021) automate and renew the process
- puts 'Manually: create a release on GitHub with relevant changelog part'
- puts 'Manually: send email same as release with relevant changelog part'
+ puts
+ puts 'Manually: create a release on GitHub, use the "Generate release notes" button'
ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java
--- /tmp/d20260623-888-cy4lhc/concurrent-ruby-1.3.6/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java 2026-06-23 23:38:02.581830566 +0000
+++ /tmp/d20260623-888-cy4lhc/concurrent-ruby-1.3.7/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java 2026-06-23 23:38:02.599830514 +0000
@@ -2,0 +3,2 @@
+import static org.jruby.runtime.Visibility.PRIVATE;
+
@@ -5 +6,0 @@
-import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
@@ -9 +9,0 @@
-import org.jruby.RubyNumeric;
@@ -94 +94 @@
- @JRubyMethod(name = {"compare_and_set", "compare_and_swap"})
+ @JRubyMethod(name = "_compare_and_set", visibility = PRIVATE)
@@ -97,6 +96,0 @@
-
- if (expectedValue instanceof RubyNumeric) {
- // numerics are not always idempotent in Ruby, so we need to do slower logic
- return compareAndSetNumeric(context, expectedValue, newValue);
- }
-
@@ -113,29 +106,0 @@
- }
- }
- }
-
- private IRubyObject compareAndSetNumeric(ThreadContext context, IRubyObject expectedValue, IRubyObject newValue) {
- Ruby runtime = context.runtime;
-
- // loop until:
- // * reference CAS would succeed for same-valued objects
- // * current and expected have different values as determined by #equals
- while (true) {
- IRubyObject current = reference;
-
- if (!(current instanceof RubyNumeric)) {
- // old value is not numeric, CAS fails
- return runtime.getFalse();
- }
-
- RubyNumeric currentNumber = (RubyNumeric)current;
- if (!currentNumber.equals(expectedValue)) {
- // current number does not equal expected, fail CAS
- return runtime.getFalse();
- }
-
- // check that current has not changed, or else allow loop to repeat
- boolean success = UNSAFE.compareAndSwapObject(this, referenceOffset, current, newValue);
- if (success) {
- // value is same and did not change in interim...success
- return runtime.getTrue();
lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb
--- /tmp/d20260623-888-cy4lhc/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb 2026-06-23 23:38:02.586830552 +0000
+++ /tmp/d20260623-888-cy4lhc/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb 2026-06-23 23:38:02.604830500 +0000
@@ -25 +24,0 @@
- alias_method :compare_and_swap, :compare_and_set
@@ -32,0 +32 @@
+ include AtomicNumericCompareAndSetWrapper
@@ -37,0 +38,8 @@
+ if private_method_defined?(:compare_and_set_reference)
+ alias_method :_compare_and_set, :compare_and_set_reference
+ private :_compare_and_set
+ include AtomicNumericCompareAndSetWrapper
+ else
+ # AtomicNumericCompareAndSetWrapper behavior already in TruffleRuby::AtomicReference
+ alias_method :compare_and_swap, :compare_and_set
+ end
@@ -40 +47,0 @@
- alias_method :compare_and_swap, :compare_and_set
lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb
--- /tmp/d20260623-888-cy4lhc/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb 2026-06-23 23:38:02.587830549 +0000
+++ /tmp/d20260623-888-cy4lhc/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb 2026-06-23 23:38:02.605830497 +0000
@@ -2,0 +3 @@
+require 'concurrent/atomic/atomic_reference'
@@ -61 +62,2 @@
- @Counter = AtomicFixnum.new(0) # single integer which represents lock state
+ @Counter = AtomicFixnum.new(0) # single integer which represents lock state
+ @Writer = AtomicReference.new(nil) # the thread currently holding the write lock
@@ -139,0 +142,2 @@
+ #
+ # @raise [Concurrent::IllegalOperationError] if no read lock is currently held.
@@ -142,0 +147,2 @@
+ raise IllegalOperationError, 'Cannot release a read lock which is not held' if running_readers(c) == 0
+
@@ -189,0 +196 @@
+ @Writer.set(Thread.current)
@@ -195,0 +203,3 @@
+ #
+ # @raise [Concurrent::IllegalOperationError] if the write lock is not held
+ # by the current thread.
@@ -197 +207,4 @@
- return true unless running_writer?
+ unless @Writer.compare_and_set(Thread.current, nil)
+ raise IllegalOperationError, 'Cannot release a write lock which is not held by the current thread'
+ end
+
lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb
--- /tmp/d20260623-888-cy4lhc/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb 2026-06-23 23:38:02.587830549 +0000
+++ /tmp/d20260623-888-cy4lhc/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb 2026-06-23 23:38:02.605830497 +0000
@@ -161 +161 @@
- # is exceeded.
+ # or per-thread reentrant acquires is exceeded.
@@ -163,0 +164,2 @@
+ raise ResourceLimitError.new('Too many reader holds on this thread') if (held & READ_LOCK_MASK) == READ_LOCK_MASK
+
@@ -214,0 +217,3 @@
+ #
+ # @raise [Concurrent::ResourceLimitError] if the maximum number of per-thread
+ # reentrant acquires is exceeded.
@@ -216,0 +222,2 @@
+ raise ResourceLimitError.new('Too many reader holds on this thread') if (held & READ_LOCK_MASK) == READ_LOCK_MASK
+
lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb
--- /tmp/d20260623-888-cy4lhc/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb 2026-06-23 23:38:02.588830546 +0000
+++ /tmp/d20260623-888-cy4lhc/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb 2026-06-23 23:38:02.605830497 +0000
@@ -13 +12,0 @@
- alias_method :compare_and_swap, :compare_and_set
@@ -45 +44 @@
- def _compare_and_set(old_value, new_value)
+ private def _compare_and_set(old_value, new_value)
lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb
--- /tmp/d20260623-888-cy4lhc/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb 2026-06-23 23:38:02.588830546 +0000
+++ /tmp/d20260623-888-cy4lhc/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb 2026-06-23 23:38:02.605830497 +0000
@@ -11,0 +12,2 @@
+ # NaN is never == to itself; match it explicitly so #update can terminate.
+ expected_nan = old_value.respond_to?(:nan?) && old_value.nan?
@@ -17 +19,5 @@
- return false unless old == old_value
+ if expected_nan
+ return false unless old.respond_to?(:nan?) && old.nan?
+ else
+ return false unless old == old_value
+ end
@@ -25,0 +32,2 @@
+
+ alias_method :compare_and_swap, :compare_and_set
lib/concurrent-ruby/concurrent/concurrent_ruby.jar
Binary files /tmp/d20260623-888-cy4lhc/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/concurrent_ruby.jar and /tmp/d20260623-888-cy4lhc/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/concurrent_ruby.jar differ
lib/concurrent-ruby/concurrent/version.rb
--- /tmp/d20260623-888-cy4lhc/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/version.rb 2026-06-23 23:38:02.598830517 +0000
+++ /tmp/d20260623-888-cy4lhc/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/version.rb 2026-06-23 23:38:02.615830468 +0000
@@ -2 +2 @@
- VERSION = '1.3.6'
+ VERSION = '1.3.7' |
Contributor
gem compare --diff concurrent-ruby 1.3.6 1.3.7Compared versions: ["1.3.6", "1.3.7"]
DIFFERENT files:
1.3.6->1.3.7:
* Changed:
CHANGELOG.md
--- /tmp/d20260623-887-ier7ip/concurrent-ruby-1.3.6/CHANGELOG.md 2026-06-23 23:38:07.818301320 +0000
+++ /tmp/d20260623-887-ier7ip/concurrent-ruby-1.3.7/CHANGELOG.md 2026-06-23 23:38:07.834301689 +0000
@@ -2,0 +3,6 @@
+## Release v1.3.7 (16 June 2026)
+
+concurrent-ruby:
+
+* See the [release notes on GitHub](https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.3.7).
+
Rakefile
--- /tmp/d20260623-887-ier7ip/concurrent-ruby-1.3.6/Rakefile 2026-06-23 23:38:07.818301320 +0000
+++ /tmp/d20260623-887-ier7ip/concurrent-ruby-1.3.7/Rakefile 2026-06-23 23:38:07.834301689 +0000
@@ -338,3 +338,2 @@
- # TODO: (petr 05-Jun-2021) automate and renew the process
- puts 'Manually: create a release on GitHub with relevant changelog part'
- puts 'Manually: send email same as release with relevant changelog part'
+ puts
+ puts 'Manually: create a release on GitHub, use the "Generate release notes" button'
ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java
--- /tmp/d20260623-887-ier7ip/concurrent-ruby-1.3.6/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java 2026-06-23 23:38:07.819301343 +0000
+++ /tmp/d20260623-887-ier7ip/concurrent-ruby-1.3.7/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java 2026-06-23 23:38:07.835301712 +0000
@@ -2,0 +3,2 @@
+import static org.jruby.runtime.Visibility.PRIVATE;
+
@@ -5 +6,0 @@
-import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
@@ -9 +9,0 @@
-import org.jruby.RubyNumeric;
@@ -94 +94 @@
- @JRubyMethod(name = {"compare_and_set", "compare_and_swap"})
+ @JRubyMethod(name = "_compare_and_set", visibility = PRIVATE)
@@ -97,6 +96,0 @@
-
- if (expectedValue instanceof RubyNumeric) {
- // numerics are not always idempotent in Ruby, so we need to do slower logic
- return compareAndSetNumeric(context, expectedValue, newValue);
- }
-
@@ -113,29 +106,0 @@
- }
- }
- }
-
- private IRubyObject compareAndSetNumeric(ThreadContext context, IRubyObject expectedValue, IRubyObject newValue) {
- Ruby runtime = context.runtime;
-
- // loop until:
- // * reference CAS would succeed for same-valued objects
- // * current and expected have different values as determined by #equals
- while (true) {
- IRubyObject current = reference;
-
- if (!(current instanceof RubyNumeric)) {
- // old value is not numeric, CAS fails
- return runtime.getFalse();
- }
-
- RubyNumeric currentNumber = (RubyNumeric)current;
- if (!currentNumber.equals(expectedValue)) {
- // current number does not equal expected, fail CAS
- return runtime.getFalse();
- }
-
- // check that current has not changed, or else allow loop to repeat
- boolean success = UNSAFE.compareAndSwapObject(this, referenceOffset, current, newValue);
- if (success) {
- // value is same and did not change in interim...success
- return runtime.getTrue();
lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb
--- /tmp/d20260623-887-ier7ip/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb 2026-06-23 23:38:07.824301458 +0000
+++ /tmp/d20260623-887-ier7ip/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb 2026-06-23 23:38:07.839301804 +0000
@@ -25 +24,0 @@
- alias_method :compare_and_swap, :compare_and_set
@@ -32,0 +32 @@
+ include AtomicNumericCompareAndSetWrapper
@@ -37,0 +38,8 @@
+ if private_method_defined?(:compare_and_set_reference)
+ alias_method :_compare_and_set, :compare_and_set_reference
+ private :_compare_and_set
+ include AtomicNumericCompareAndSetWrapper
+ else
+ # AtomicNumericCompareAndSetWrapper behavior already in TruffleRuby::AtomicReference
+ alias_method :compare_and_swap, :compare_and_set
+ end
@@ -40 +47,0 @@
- alias_method :compare_and_swap, :compare_and_set
lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb
--- /tmp/d20260623-887-ier7ip/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb 2026-06-23 23:38:07.824301458 +0000
+++ /tmp/d20260623-887-ier7ip/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb 2026-06-23 23:38:07.840301827 +0000
@@ -2,0 +3 @@
+require 'concurrent/atomic/atomic_reference'
@@ -61 +62,2 @@
- @Counter = AtomicFixnum.new(0) # single integer which represents lock state
+ @Counter = AtomicFixnum.new(0) # single integer which represents lock state
+ @Writer = AtomicReference.new(nil) # the thread currently holding the write lock
@@ -139,0 +142,2 @@
+ #
+ # @raise [Concurrent::IllegalOperationError] if no read lock is currently held.
@@ -142,0 +147,2 @@
+ raise IllegalOperationError, 'Cannot release a read lock which is not held' if running_readers(c) == 0
+
@@ -189,0 +196 @@
+ @Writer.set(Thread.current)
@@ -195,0 +203,3 @@
+ #
+ # @raise [Concurrent::IllegalOperationError] if the write lock is not held
+ # by the current thread.
@@ -197 +207,4 @@
- return true unless running_writer?
+ unless @Writer.compare_and_set(Thread.current, nil)
+ raise IllegalOperationError, 'Cannot release a write lock which is not held by the current thread'
+ end
+
lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb
--- /tmp/d20260623-887-ier7ip/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb 2026-06-23 23:38:07.825301481 +0000
+++ /tmp/d20260623-887-ier7ip/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb 2026-06-23 23:38:07.840301827 +0000
@@ -161 +161 @@
- # is exceeded.
+ # or per-thread reentrant acquires is exceeded.
@@ -163,0 +164,2 @@
+ raise ResourceLimitError.new('Too many reader holds on this thread') if (held & READ_LOCK_MASK) == READ_LOCK_MASK
+
@@ -214,0 +217,3 @@
+ #
+ # @raise [Concurrent::ResourceLimitError] if the maximum number of per-thread
+ # reentrant acquires is exceeded.
@@ -216,0 +222,2 @@
+ raise ResourceLimitError.new('Too many reader holds on this thread') if (held & READ_LOCK_MASK) == READ_LOCK_MASK
+
lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb
--- /tmp/d20260623-887-ier7ip/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb 2026-06-23 23:38:07.825301481 +0000
+++ /tmp/d20260623-887-ier7ip/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb 2026-06-23 23:38:07.840301827 +0000
@@ -13 +12,0 @@
- alias_method :compare_and_swap, :compare_and_set
@@ -45 +44 @@
- def _compare_and_set(old_value, new_value)
+ private def _compare_and_set(old_value, new_value)
lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb
--- /tmp/d20260623-887-ier7ip/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb 2026-06-23 23:38:07.825301481 +0000
+++ /tmp/d20260623-887-ier7ip/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb 2026-06-23 23:38:07.840301827 +0000
@@ -11,0 +12,2 @@
+ # NaN is never == to itself; match it explicitly so #update can terminate.
+ expected_nan = old_value.respond_to?(:nan?) && old_value.nan?
@@ -17 +19,5 @@
- return false unless old == old_value
+ if expected_nan
+ return false unless old.respond_to?(:nan?) && old.nan?
+ else
+ return false unless old == old_value
+ end
@@ -25,0 +32,2 @@
+
+ alias_method :compare_and_swap, :compare_and_set
lib/concurrent-ruby/concurrent/concurrent_ruby.jar
Binary files /tmp/d20260623-887-ier7ip/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/concurrent_ruby.jar and /tmp/d20260623-887-ier7ip/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/concurrent_ruby.jar differ
lib/concurrent-ruby/concurrent/version.rb
--- /tmp/d20260623-887-ier7ip/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/version.rb 2026-06-23 23:38:07.833301666 +0000
+++ /tmp/d20260623-887-ier7ip/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/version.rb 2026-06-23 23:38:07.849302034 +0000
@@ -2 +2 @@
- VERSION = '1.3.6'
+ VERSION = '1.3.7' |
Contributor
gem compare --diff concurrent-ruby 1.3.6 1.3.7Compared versions: ["1.3.6", "1.3.7"]
DIFFERENT files:
1.3.6->1.3.7:
* Changed:
CHANGELOG.md
--- /tmp/d20260623-996-1t66nz/concurrent-ruby-1.3.6/CHANGELOG.md 2026-06-23 23:39:31.641277165 +0000
+++ /tmp/d20260623-996-1t66nz/concurrent-ruby-1.3.7/CHANGELOG.md 2026-06-23 23:39:31.659277234 +0000
@@ -2,0 +3,6 @@
+## Release v1.3.7 (16 June 2026)
+
+concurrent-ruby:
+
+* See the [release notes on GitHub](https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.3.7).
+
Rakefile
--- /tmp/d20260623-996-1t66nz/concurrent-ruby-1.3.6/Rakefile 2026-06-23 23:39:31.641277165 +0000
+++ /tmp/d20260623-996-1t66nz/concurrent-ruby-1.3.7/Rakefile 2026-06-23 23:39:31.659277234 +0000
@@ -338,3 +338,2 @@
- # TODO: (petr 05-Jun-2021) automate and renew the process
- puts 'Manually: create a release on GitHub with relevant changelog part'
- puts 'Manually: send email same as release with relevant changelog part'
+ puts
+ puts 'Manually: create a release on GitHub, use the "Generate release notes" button'
ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java
--- /tmp/d20260623-996-1t66nz/concurrent-ruby-1.3.6/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java 2026-06-23 23:39:31.642277169 +0000
+++ /tmp/d20260623-996-1t66nz/concurrent-ruby-1.3.7/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java 2026-06-23 23:39:31.660277238 +0000
@@ -2,0 +3,2 @@
+import static org.jruby.runtime.Visibility.PRIVATE;
+
@@ -5 +6,0 @@
-import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
@@ -9 +9,0 @@
-import org.jruby.RubyNumeric;
@@ -94 +94 @@
- @JRubyMethod(name = {"compare_and_set", "compare_and_swap"})
+ @JRubyMethod(name = "_compare_and_set", visibility = PRIVATE)
@@ -97,6 +96,0 @@
-
- if (expectedValue instanceof RubyNumeric) {
- // numerics are not always idempotent in Ruby, so we need to do slower logic
- return compareAndSetNumeric(context, expectedValue, newValue);
- }
-
@@ -113,29 +106,0 @@
- }
- }
- }
-
- private IRubyObject compareAndSetNumeric(ThreadContext context, IRubyObject expectedValue, IRubyObject newValue) {
- Ruby runtime = context.runtime;
-
- // loop until:
- // * reference CAS would succeed for same-valued objects
- // * current and expected have different values as determined by #equals
- while (true) {
- IRubyObject current = reference;
-
- if (!(current instanceof RubyNumeric)) {
- // old value is not numeric, CAS fails
- return runtime.getFalse();
- }
-
- RubyNumeric currentNumber = (RubyNumeric)current;
- if (!currentNumber.equals(expectedValue)) {
- // current number does not equal expected, fail CAS
- return runtime.getFalse();
- }
-
- // check that current has not changed, or else allow loop to repeat
- boolean success = UNSAFE.compareAndSwapObject(this, referenceOffset, current, newValue);
- if (success) {
- // value is same and did not change in interim...success
- return runtime.getTrue();
lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb
--- /tmp/d20260623-996-1t66nz/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb 2026-06-23 23:39:31.647277188 +0000
+++ /tmp/d20260623-996-1t66nz/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb 2026-06-23 23:39:31.664277253 +0000
@@ -25 +24,0 @@
- alias_method :compare_and_swap, :compare_and_set
@@ -32,0 +32 @@
+ include AtomicNumericCompareAndSetWrapper
@@ -37,0 +38,8 @@
+ if private_method_defined?(:compare_and_set_reference)
+ alias_method :_compare_and_set, :compare_and_set_reference
+ private :_compare_and_set
+ include AtomicNumericCompareAndSetWrapper
+ else
+ # AtomicNumericCompareAndSetWrapper behavior already in TruffleRuby::AtomicReference
+ alias_method :compare_and_swap, :compare_and_set
+ end
@@ -40 +47,0 @@
- alias_method :compare_and_swap, :compare_and_set
lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb
--- /tmp/d20260623-996-1t66nz/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb 2026-06-23 23:39:31.648277192 +0000
+++ /tmp/d20260623-996-1t66nz/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb 2026-06-23 23:39:31.665277257 +0000
@@ -2,0 +3 @@
+require 'concurrent/atomic/atomic_reference'
@@ -61 +62,2 @@
- @Counter = AtomicFixnum.new(0) # single integer which represents lock state
+ @Counter = AtomicFixnum.new(0) # single integer which represents lock state
+ @Writer = AtomicReference.new(nil) # the thread currently holding the write lock
@@ -139,0 +142,2 @@
+ #
+ # @raise [Concurrent::IllegalOperationError] if no read lock is currently held.
@@ -142,0 +147,2 @@
+ raise IllegalOperationError, 'Cannot release a read lock which is not held' if running_readers(c) == 0
+
@@ -189,0 +196 @@
+ @Writer.set(Thread.current)
@@ -195,0 +203,3 @@
+ #
+ # @raise [Concurrent::IllegalOperationError] if the write lock is not held
+ # by the current thread.
@@ -197 +207,4 @@
- return true unless running_writer?
+ unless @Writer.compare_and_set(Thread.current, nil)
+ raise IllegalOperationError, 'Cannot release a write lock which is not held by the current thread'
+ end
+
lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb
--- /tmp/d20260623-996-1t66nz/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb 2026-06-23 23:39:31.648277192 +0000
+++ /tmp/d20260623-996-1t66nz/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb 2026-06-23 23:39:31.665277257 +0000
@@ -161 +161 @@
- # is exceeded.
+ # or per-thread reentrant acquires is exceeded.
@@ -163,0 +164,2 @@
+ raise ResourceLimitError.new('Too many reader holds on this thread') if (held & READ_LOCK_MASK) == READ_LOCK_MASK
+
@@ -214,0 +217,3 @@
+ #
+ # @raise [Concurrent::ResourceLimitError] if the maximum number of per-thread
+ # reentrant acquires is exceeded.
@@ -216,0 +222,2 @@
+ raise ResourceLimitError.new('Too many reader holds on this thread') if (held & READ_LOCK_MASK) == READ_LOCK_MASK
+
lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb
--- /tmp/d20260623-996-1t66nz/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb 2026-06-23 23:39:31.648277192 +0000
+++ /tmp/d20260623-996-1t66nz/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb 2026-06-23 23:39:31.665277257 +0000
@@ -13 +12,0 @@
- alias_method :compare_and_swap, :compare_and_set
@@ -45 +44 @@
- def _compare_and_set(old_value, new_value)
+ private def _compare_and_set(old_value, new_value)
lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb
--- /tmp/d20260623-996-1t66nz/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb 2026-06-23 23:39:31.648277192 +0000
+++ /tmp/d20260623-996-1t66nz/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb 2026-06-23 23:39:31.665277257 +0000
@@ -11,0 +12,2 @@
+ # NaN is never == to itself; match it explicitly so #update can terminate.
+ expected_nan = old_value.respond_to?(:nan?) && old_value.nan?
@@ -17 +19,5 @@
- return false unless old == old_value
+ if expected_nan
+ return false unless old.respond_to?(:nan?) && old.nan?
+ else
+ return false unless old == old_value
+ end
@@ -25,0 +32,2 @@
+
+ alias_method :compare_and_swap, :compare_and_set
lib/concurrent-ruby/concurrent/concurrent_ruby.jar
Binary files /tmp/d20260623-996-1t66nz/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/concurrent_ruby.jar and /tmp/d20260623-996-1t66nz/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/concurrent_ruby.jar differ
lib/concurrent-ruby/concurrent/version.rb
--- /tmp/d20260623-996-1t66nz/concurrent-ruby-1.3.6/lib/concurrent-ruby/concurrent/version.rb 2026-06-23 23:39:31.658277230 +0000
+++ /tmp/d20260623-996-1t66nz/concurrent-ruby-1.3.7/lib/concurrent-ruby/concurrent/version.rb 2026-06-23 23:39:31.675277295 +0000
@@ -2 +2 @@
- VERSION = '1.3.6'
+ VERSION = '1.3.7' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bumps concurrent-ruby from 1.3.6 to 1.3.7.
Release notes
Sourced from concurrent-ruby's releases.
Changelog
Sourced from concurrent-ruby's changelog.
Commits
4c8fc28Release 1.3.7d91ca94Fix AtomicReference#update livelock when stored value is Float::NAN on JRuby ...7e4d711FixReentrantReadWriteLockread hold overflow into write-lock bit6e37e06FixAtomicReference#updatelivelock when stored value isFloat::NAN2825cfaCleanup spec3fd4932FixReadWriteLockwrong-thread write release and stray read release1974b47Add Ruby 4.0 in CIdf8706dAdd SECURITY.md (#1104)7a1b789Bump actions/upload-pages-artifact from 4 to 59b2dbf7Bump actions/deploy-pages from 4 to 5Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting
@dependabot rebase.Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
@dependabot rebasewill rebase this PR@dependabot recreatewill recreate this PR, overwriting any edits that have been made to it@dependabot show <dependency name> ignore conditionswill show all of the ignore conditions of the specified dependency@dependabot ignore this major versionwill close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this minor versionwill close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this dependencywill close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)You can disable automated security fix PRs for this repo from the Security Alerts page.