concurrent-ruby 1.1.10 → 1.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +76 -3
  3. data/Gemfile +6 -7
  4. data/README.md +28 -23
  5. data/Rakefile +90 -76
  6. data/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java +3 -38
  7. data/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java +10 -25
  8. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java +1 -1
  9. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/ConcurrentHashMapV8.java +1 -1
  10. data/lib/concurrent-ruby/concurrent/agent.rb +4 -3
  11. data/lib/concurrent-ruby/concurrent/array.rb +3 -13
  12. data/lib/concurrent-ruby/concurrent/async.rb +1 -1
  13. data/lib/concurrent-ruby/concurrent/atom.rb +2 -2
  14. data/lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb +5 -4
  15. data/lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb +5 -4
  16. data/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb +3 -0
  17. data/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb +90 -153
  18. data/lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb +1 -1
  19. data/lib/concurrent-ruby/concurrent/atomic/event.rb +1 -1
  20. data/lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb +109 -0
  21. data/lib/concurrent-ruby/concurrent/atomic/java_count_down_latch.rb +1 -0
  22. data/lib/concurrent-ruby/concurrent/atomic/locals.rb +189 -0
  23. data/lib/concurrent-ruby/concurrent/atomic/lock_local_var.rb +29 -0
  24. data/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_boolean.rb +11 -5
  25. data/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_fixnum.rb +11 -5
  26. data/lib/concurrent-ruby/concurrent/atomic/mutex_count_down_latch.rb +1 -1
  27. data/lib/concurrent-ruby/concurrent/atomic/mutex_semaphore.rb +1 -1
  28. data/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb +17 -3
  29. data/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb +13 -4
  30. data/lib/concurrent-ruby/concurrent/atomic/semaphore.rb +6 -9
  31. data/lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb +96 -89
  32. data/lib/concurrent-ruby/concurrent/atomic_reference/atomic_direct_update.rb +37 -0
  33. data/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb +16 -6
  34. data/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb +9 -1
  35. data/lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb +1 -1
  36. data/lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb +1 -1
  37. data/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb +2 -0
  38. data/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb +2 -2
  39. data/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb +16 -8
  40. data/lib/concurrent-ruby/concurrent/collection/map/synchronized_map_backend.rb +23 -20
  41. data/lib/concurrent-ruby/concurrent/collection/ruby_timeout_queue.rb +55 -0
  42. data/lib/concurrent-ruby/concurrent/collection/timeout_queue.rb +18 -0
  43. data/lib/concurrent-ruby/concurrent/concern/logging.rb +95 -6
  44. data/lib/concurrent-ruby/concurrent/concurrent_ruby.jar +0 -0
  45. data/lib/concurrent-ruby/concurrent/configuration.rb +4 -87
  46. data/lib/concurrent-ruby/concurrent/delay.rb +3 -3
  47. data/lib/concurrent-ruby/concurrent/errors.rb +5 -0
  48. data/lib/concurrent-ruby/concurrent/exchanger.rb +1 -0
  49. data/lib/concurrent-ruby/concurrent/executor/abstract_executor_service.rb +1 -1
  50. data/lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb +6 -4
  51. data/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb +7 -9
  52. data/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb +7 -0
  53. data/lib/concurrent-ruby/concurrent/executor/ruby_single_thread_executor.rb +2 -0
  54. data/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb +61 -31
  55. data/lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb +1 -1
  56. data/lib/concurrent-ruby/concurrent/executor/serialized_execution.rb +1 -1
  57. data/lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb +4 -1
  58. data/lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb +1 -1
  59. data/lib/concurrent-ruby/concurrent/executor/timer_set.rb +10 -3
  60. data/lib/concurrent-ruby/concurrent/executors.rb +0 -1
  61. data/lib/concurrent-ruby/concurrent/hash.rb +5 -12
  62. data/lib/concurrent-ruby/concurrent/immutable_struct.rb +1 -1
  63. data/lib/concurrent-ruby/concurrent/ivar.rb +2 -1
  64. data/lib/concurrent-ruby/concurrent/map.rb +43 -39
  65. data/lib/concurrent-ruby/concurrent/maybe.rb +1 -1
  66. data/lib/concurrent-ruby/concurrent/mutable_struct.rb +1 -1
  67. data/lib/concurrent-ruby/concurrent/mvar.rb +5 -5
  68. data/lib/concurrent-ruby/concurrent/promise.rb +3 -3
  69. data/lib/concurrent-ruby/concurrent/promises.rb +40 -29
  70. data/lib/concurrent-ruby/concurrent/re_include.rb +2 -0
  71. data/lib/concurrent-ruby/concurrent/scheduled_task.rb +2 -2
  72. data/lib/concurrent-ruby/concurrent/set.rb +0 -10
  73. data/lib/concurrent-ruby/concurrent/settable_struct.rb +2 -2
  74. data/lib/concurrent-ruby/concurrent/synchronization/abstract_lockable_object.rb +5 -1
  75. data/lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb +1 -3
  76. data/lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb +1 -1
  77. data/lib/concurrent-ruby/concurrent/synchronization/condition.rb +2 -0
  78. data/lib/concurrent-ruby/concurrent/synchronization/full_memory_barrier.rb +29 -0
  79. data/lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb +3 -1
  80. data/lib/concurrent-ruby/concurrent/synchronization/lock.rb +2 -0
  81. data/lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb +5 -2
  82. data/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb +6 -5
  83. data/lib/concurrent-ruby/concurrent/synchronization/object.rb +13 -45
  84. data/lib/concurrent-ruby/concurrent/synchronization/safe_initialization.rb +36 -0
  85. data/lib/concurrent-ruby/concurrent/synchronization/volatile.rb +77 -12
  86. data/lib/concurrent-ruby/concurrent/synchronization.rb +1 -18
  87. data/lib/concurrent-ruby/concurrent/thread_safe/synchronized_delegator.rb +36 -39
  88. data/lib/concurrent-ruby/concurrent/thread_safe/util/adder.rb +1 -1
  89. data/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb +1 -37
  90. data/lib/concurrent-ruby/concurrent/thread_safe/util/xor_shift_random.rb +1 -1
  91. data/lib/concurrent-ruby/concurrent/timer_task.rb +65 -10
  92. data/lib/concurrent-ruby/concurrent/tuple.rb +1 -5
  93. data/lib/concurrent-ruby/concurrent/tvar.rb +2 -1
  94. data/lib/concurrent-ruby/concurrent/utility/engine.rb +5 -16
  95. data/lib/concurrent-ruby/concurrent/utility/monotonic_time.rb +3 -74
  96. data/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb +8 -10
  97. data/lib/concurrent-ruby/concurrent/utility/native_integer.rb +1 -0
  98. data/lib/concurrent-ruby/concurrent/utility/processor_counter.rb +148 -58
  99. data/lib/concurrent-ruby/concurrent/version.rb +1 -1
  100. metadata +14 -19
  101. data/lib/concurrent-ruby/concurrent/atomic/abstract_thread_local_var.rb +0 -66
  102. data/lib/concurrent-ruby/concurrent/atomic/java_thread_local_var.rb +0 -37
  103. data/lib/concurrent-ruby/concurrent/atomic/ruby_thread_local_var.rb +0 -181
  104. data/lib/concurrent-ruby/concurrent/collection/map/atomic_reference_map_backend.rb +0 -927
  105. data/lib/concurrent-ruby/concurrent/synchronization/jruby_object.rb +0 -45
  106. data/lib/concurrent-ruby/concurrent/synchronization/mri_object.rb +0 -44
  107. data/lib/concurrent-ruby/concurrent/synchronization/rbx_lockable_object.rb +0 -71
  108. data/lib/concurrent-ruby/concurrent/synchronization/rbx_object.rb +0 -49
  109. data/lib/concurrent-ruby/concurrent/synchronization/truffleruby_object.rb +0 -47
  110. data/lib/concurrent-ruby/concurrent/thread_safe/util/cheap_lockable.rb +0 -118
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e2508d8671dc3f93a6d41204a69a2444669688ac1e9e7790104162ac5180579e
4
- data.tar.gz: 5eba3636194c783d376ed010bd3d6ec8796fe409870e07a84c6b0b0ea2704b41
3
+ metadata.gz: 0d094624e5f9f2dffc45b80892987f339d8b8c09ff2f01cf923e3825dd6409f7
4
+ data.tar.gz: 02adb496e81a3adb7e3c6042f72ec421677851033d57eb77b0e1b3641ef70684
5
5
  SHA512:
6
- metadata.gz: 4c1cbc5311e939aecda5e291bb579a690807de5240bb2fb30600a9d1d9de8c353558de7d6e3e0dff871fcca364bd7caa76b304428e0fdaba323cbe04be300056
7
- data.tar.gz: 863635cad877062864813b9ba72685b3afdadabf258a62b36f8d7093a5be9c7115d64aade01c9a98b9e68ef86dff2698e5e0cef7766b9c4dfc740e0e76eccf0c
6
+ metadata.gz: 43a4af037c64d4ee8e128963db7a3f40213a45898289bb9143aa222e5664982b8c0fa08d2dae8e629fa7766be6a528b74b5ba17fbbb5cb741a9b5c08020eea15
7
+ data.tar.gz: 0203e085d78340af99c8d8cbf2f0aa8793db6bfdbe4c25cd2ff622816581004c2871851c621d23bcfd653be30fd3aca682e98a3117b64e5735d23bb2a3bfb4c0
data/CHANGELOG.md CHANGED
@@ -1,6 +1,79 @@
1
1
  ## Current
2
2
 
3
- ## Release v1.1.10
3
+ ## Release v1.3.7 (16 June 2026)
4
+
5
+ concurrent-ruby:
6
+
7
+ * See the [release notes on GitHub](https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.3.7).
8
+
9
+ ## Release v1.3.6 (13 December 2025)
10
+
11
+ concurrent-ruby:
12
+
13
+ * See the [release notes on GitHub](https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.3.6).
14
+
15
+ ## Release v1.3.5, edge v0.7.2 (15 January 2025)
16
+
17
+ concurrent-ruby:
18
+
19
+ * (#1062) Remove dependency on logger.
20
+
21
+ concurrent-ruby-edge:
22
+
23
+ * (#1062) Remove dependency on logger.
24
+
25
+ ## Release v1.3.4 (10 August 2024)
26
+
27
+ * (#1060) Fix bug with return value of `Concurrent.available_processor_count` when `cpu.cfs_quota_us` is -1.
28
+ * (#1058) Add `Concurrent.cpu_shares` that is cgroups aware.
29
+
30
+ ## Release v1.3.3 (9 June 2024)
31
+
32
+ * (#1053) Improve the speed of `Concurrent.physical_processor_count` on Windows.
33
+
34
+ ## Release v1.3.2, edge v0.7.1 (7 June 2024)
35
+
36
+ concurrent-ruby:
37
+
38
+ * (#1051) Remove dependency on `win32ole`.
39
+
40
+ concurrent-ruby-edge:
41
+
42
+ * (#1052) Fix dependency on `concurrent-ruby` to allow the latest release.
43
+
44
+ ## Release v1.3.1 (29 May 2024)
45
+
46
+ * Release 1.3.0 was broken when pushed to RubyGems. 1.3.1 is a packaging fix.
47
+
48
+ ## Release v1.3.0 (28 May 2024)
49
+
50
+ * (#1042) Align Java Executor Service behavior for `shuttingdown?`, `shutdown?`
51
+ * (#1038) Add `Concurrent.available_processor_count` that is cgroups aware.
52
+
53
+ ## Release v1.2.3 (16 Jan 2024)
54
+
55
+ * See [the GitHub release](https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.2.3) for details.
56
+
57
+ ## Release v1.2.2 (24 Feb 2023)
58
+
59
+ * (#993) Fix arguments passed to `Concurrent::Map`'s `default_proc`.
60
+
61
+ ## Release v1.2.1 (24 Feb 2023)
62
+
63
+ * (#990) Add missing `require 'fiber'` for `FiberLocalVar`.
64
+ * (#989) Optimize `Concurrent::Map#[]` on CRuby by letting the backing Hash handle the `default_proc`.
65
+
66
+ ## Release v1.2.0 (23 Jan 2023)
67
+
68
+ * (#962) Fix ReentrantReadWriteLock to use the same granularity for locals as for Mutex it uses.
69
+ * (#983) Add FiberLocalVar
70
+ * (#934) concurrent-ruby now supports requiring individual classes (public classes listed in the docs), e.g., `require 'concurrent/map'`
71
+ * (#976) Let `Promises.any_fulfilled_future` take an `Event`
72
+ * Improve documentation of various classes
73
+ * (#975) Set the Ruby compatibility version at 2.3
74
+ * (#972) Remove Rubinius-related code
75
+
76
+ ## Release v1.1.10 (22 Mar 2022)
4
77
 
5
78
  concurrent-ruby:
6
79
 
@@ -245,7 +318,7 @@ concurrent-ruby-edge:
245
318
  * Simplification of `RubySingleThreadExecutor`
246
319
  * `Async` improvements
247
320
  - Each object uses its own `SingleThreadExecutor` instead of the global thread pool.
248
- - No longers supports executor injection
321
+ - No longer supports executor injection
249
322
  - Much better documentation
250
323
  * `Atom` updates
251
324
  - No longer `Dereferenceable`
@@ -420,7 +493,7 @@ Please see the [roadmap](https://github.com/ruby-concurrency/concurrent-ruby/iss
420
493
  * Fixed bug with return value of `Concurrent::Actor::Utils::Pool#ask`
421
494
  * Fixed timing bug in `TimerTask`
422
495
  * Fixed bug when creating a `JavaThreadPoolExecutor` with minimum pool size of zero
423
- * Removed confusing warning when not using native extenstions
496
+ * Removed confusing warning when not using native extensions
424
497
  * Improved documentation
425
498
 
426
499
  ## Release v0.7.0 (13 August 2014)
data/Gemfile CHANGED
@@ -1,19 +1,18 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- require File.join(File.dirname(__FILE__), 'lib/concurrent-ruby/concurrent/version')
4
- require File.join(File.dirname(__FILE__ ), 'lib/concurrent-ruby-edge/concurrent/edge/version')
5
- require File.join(File.dirname(__FILE__ ), 'lib/concurrent-ruby/concurrent/utility/engine')
3
+ version = File.read("#{__dir__}/lib/concurrent-ruby/concurrent/version.rb")[/'(.+)'/, 1] or raise
4
+ edge_version = File.read("#{__dir__}/lib/concurrent-ruby-edge/concurrent/edge/version.rb")[/'(.+)'/, 1] or raise
6
5
 
7
6
  no_path = ENV['NO_PATH']
8
7
  options = no_path ? {} : { path: '.' }
9
8
 
10
- gem 'concurrent-ruby', Concurrent::VERSION, options
11
- gem 'concurrent-ruby-edge', Concurrent::EDGE_VERSION, options
12
- gem 'concurrent-ruby-ext', Concurrent::VERSION, options.merge(platform: :mri)
9
+ gem 'concurrent-ruby', version, options
10
+ gem 'concurrent-ruby-edge', edge_version, options
11
+ gem 'concurrent-ruby-ext', version, options.merge(platform: :mri)
13
12
 
14
13
  group :development do
15
14
  gem 'rake', '~> 13.0'
16
- gem 'rake-compiler', '~> 1.0', '>= 1.0.7'
15
+ gem 'rake-compiler', '~> 1.0', '>= 1.0.7', '!= 1.2.4'
17
16
  gem 'rake-compiler-dock', '~> 1.0'
18
17
  gem 'pry', '~> 0.11', platforms: :mri
19
18
  end
data/README.md CHANGED
@@ -42,8 +42,8 @@ You can also get started by triaging issues which may include reproducing bug re
42
42
  ## Thread Safety
43
43
 
44
44
  *Concurrent Ruby makes one of the strongest thread safety guarantees of any Ruby concurrency
45
- library, providing consistent behavior and guarantees on all four of the main Ruby interpreters
46
- (MRI/CRuby, JRuby, Rubinius, TruffleRuby).*
45
+ library, providing consistent behavior and guarantees on all three main Ruby interpreters
46
+ (MRI/CRuby, JRuby, TruffleRuby).*
47
47
 
48
48
  Every abstraction in this library is thread safe. Specific thread safety guarantees are documented
49
49
  with each abstraction.
@@ -58,9 +58,9 @@ other Ruby library, many of which support the mantra of
58
58
  Concurrent Ruby is also the only Ruby library which provides a full suite of thread safe and
59
59
  immutable variable types and data structures.
60
60
 
61
- We've also initiated discussion to document [memory model](docs-source/synchronization.md) of Ruby which
62
- would provide consistent behaviour and guarantees on all four of the main Ruby interpreters
63
- (MRI/CRuby, JRuby, Rubinius, TruffleRuby).
61
+ We've also initiated discussion to document the [memory model](docs-source/synchronization.md) of Ruby which
62
+ would provide consistent behaviour and guarantees on all three main Ruby interpreters
63
+ (MRI/CRuby, JRuby, TruffleRuby).
64
64
 
65
65
  ## Features & Documentation
66
66
 
@@ -207,7 +207,7 @@ Deprecated features are still available and bugs are being fixed, but new featur
207
207
  These are available in the `concurrent-ruby-edge` companion gem.
208
208
 
209
209
  These features are under active development and may change frequently. They are expected not to
210
- keep backward compatibility (there may also lack tests and documentation). Semantic versions will
210
+ keep backward compatibility (they may also lack tests and documentation). Semantic versions will
211
211
  be obeyed though. Features developed in `concurrent-ruby-edge` are expected to move to
212
212
  `concurrent-ruby` when final.
213
213
 
@@ -259,13 +259,10 @@ be obeyed though. Features developed in `concurrent-ruby-edge` are expected to m
259
259
 
260
260
  ## Supported Ruby versions
261
261
 
262
- * MRI 2.2 and above
262
+ * MRI 2.3 and above
263
263
  * Latest JRuby 9000
264
264
  * Latest TruffleRuby
265
265
 
266
- The legacy support for Rubinius is kept for the moment but it is no longer maintained and is liable to be removed. If you would like to help
267
- please respond to [#739](https://github.com/ruby-concurrency/concurrent-ruby/issues/739).
268
-
269
266
  ## Usage
270
267
 
271
268
  Everything within this gem can be loaded simply by requiring it:
@@ -274,7 +271,12 @@ Everything within this gem can be loaded simply by requiring it:
274
271
  require 'concurrent'
275
272
  ```
276
273
 
277
- *Requiring only specific abstractions from Concurrent Ruby is not yet supported.*
274
+ You can also require a specific abstraction [part of the public documentation](https://ruby-concurrency.github.io/concurrent-ruby/master/index.html) since concurrent-ruby 1.2.0, for example:
275
+ ```ruby
276
+ require 'concurrent/map'
277
+ require 'concurrent/atomic/atomic_reference'
278
+ require 'concurrent/executor/fixed_thread_pool'
279
+ ```
278
280
 
279
281
  To use the tools in the Edge gem it must be required separately:
280
282
 
@@ -282,7 +284,7 @@ To use the tools in the Edge gem it must be required separately:
282
284
  require 'concurrent-edge'
283
285
  ```
284
286
 
285
- If the library does not behave as expected, `Concurrent.use_stdlib_logger(Logger::DEBUG)` could
287
+ If the library does not behave as expected, `Concurrent.use_simple_logger(:DEBUG)` could
286
288
  help to reveal the problem.
287
289
 
288
290
  ## Installation
@@ -356,26 +358,28 @@ best practice is to depend on `concurrent-ruby` and let users to decide if they
356
358
  * Recent CRuby
357
359
  * JRuby, `rbenv install jruby-9.2.17.0`
358
360
  * Set env variable `CONCURRENT_JRUBY_HOME` to point to it, e.g. `/usr/local/opt/rbenv/versions/jruby-9.2.17.0`
359
- * Install Docker, required for Windows builds
361
+ * Install Docker or Podman, required for Windows builds
362
+ * If `bundle config get path` is set, use `bundle config set --local path.system true` otherwise the `gem name, path: '.'` gems won't be found (Bundler limitation).
360
363
 
361
364
  ### Publishing the Gem
362
365
 
363
366
  * Update `version.rb`
364
367
  * Update the CHANGELOG
365
- * Update the Yard documentation
366
- - Add the new version to `docs-source/signpost.md`. Needs to be done only if there are visible changes in the
367
- documentation.
368
- - Run `bundle exec rake yard` to update the master documentation and signpost.
369
- - Run `bundle exec rake yard:<new-version>` to add or update the documentation of the new version.
368
+ * Add the new version to `docs-source/signpost.md`. Needs to be done only if there are visible changes in the documentation.
370
369
  * Commit (and push) the changes.
371
- * Use `be rake release` to release the gem. It consists
372
- of `['release:checks', 'release:build', 'release:test', 'release:publish']` steps. It will ask at the end before
373
- publishing anything. Steps can also be executed individually.
370
+ * Use `bundle exec rake release` to release the gem.
371
+ It consists of `['release:checks', 'release:build', 'release:test', 'release:publish']` steps.
372
+ It will ask at the end before publishing anything. Steps can also be executed individually.
374
373
 
375
374
  ## Maintainers
376
375
 
377
- * [Chris Seaton](https://github.com/chrisseaton) — Lead maintainer, point-of-contact.
378
- * [Benoit Daloze](https://github.com/eregon) — If Chris is not available Benoit can help.
376
+ * [Benoit Daloze](https://github.com/eregon)
377
+ * [Matthew Draper](https://github.com/matthewd)
378
+ * [Rafael França](https://github.com/rafaelfranca)
379
+ * [Charles Oliver Nutter](https://github.com/headius)
380
+ * [Ben Sheldon](https://github.com/bensheldon)
381
+ * [Samuel Williams](https://github.com/ioquatix)
382
+ * [Joshua Young](https://github.com/joshuay03)
379
383
 
380
384
  ### Special Thanks to
381
385
 
@@ -386,6 +390,7 @@ best practice is to depend on `concurrent-ruby` and let users to decide if they
386
390
 
387
391
  to the past maintainers
388
392
 
393
+ * [Chris Seaton](https://github.com/chrisseaton)
389
394
  * [Petr Chalupa](https://github.com/pitr-ch)
390
395
  * [Michele Della Torre](https://github.com/mighe)
391
396
  * [Paweł Obrok](https://github.com/obrok)
data/Rakefile CHANGED
@@ -1,6 +1,5 @@
1
- require_relative 'lib/concurrent-ruby/concurrent/version'
2
- require_relative 'lib/concurrent-ruby-edge/concurrent/edge/version'
3
- require_relative 'lib/concurrent-ruby/concurrent/utility/engine'
1
+ version = File.read("#{__dir__}/lib/concurrent-ruby/concurrent/version.rb")[/'(.+)'/, 1] or raise
2
+ edge_version = File.read("#{__dir__}/lib/concurrent-ruby-edge/concurrent/edge/version.rb")[/'(.+)'/, 1] or raise
4
3
 
5
4
  core_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby.gemspec')
6
5
  ext_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby-ext.gemspec')
@@ -8,14 +7,16 @@ edge_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby-edge.
8
7
 
9
8
  require 'rake/javaextensiontask'
10
9
 
11
- ENV['JRUBY_HOME'] = ENV['CONCURRENT_JRUBY_HOME'] if ENV['CONCURRENT_JRUBY_HOME'] && !Concurrent.on_jruby?
10
+ ENV['JRUBY_HOME'] = ENV['CONCURRENT_JRUBY_HOME'] if ENV['CONCURRENT_JRUBY_HOME'] && RUBY_ENGINE != 'jruby'
12
11
 
13
12
  Rake::JavaExtensionTask.new('concurrent_ruby', core_gemspec) do |ext|
14
13
  ext.ext_dir = 'ext/concurrent-ruby'
15
14
  ext.lib_dir = 'lib/concurrent-ruby/concurrent'
15
+ ext.source_version = '8'
16
+ ext.target_version = '8'
16
17
  end
17
18
 
18
- unless Concurrent.on_jruby? || Concurrent.on_truffleruby?
19
+ if RUBY_ENGINE == 'ruby'
19
20
  require 'rake/extensiontask'
20
21
 
21
22
  Rake::ExtensionTask.new('concurrent_ruby_ext', ext_gemspec) do |ext|
@@ -28,20 +29,37 @@ unless Concurrent.on_jruby? || Concurrent.on_truffleruby?
28
29
  end
29
30
  end
30
31
 
32
+ def which?(executable)
33
+ !`which #{executable} 2>/dev/null`.empty?
34
+ end
35
+
31
36
  require 'rake_compiler_dock'
32
37
  namespace :repackage do
33
38
  desc '* with Windows fat distributions'
34
39
  task :all do
35
40
  Dir.chdir(__dir__) do
36
41
  # store gems in vendor cache for docker
37
- sh 'bundle package'
42
+ Bundler.with_original_env do
43
+ sh 'bundle package'
44
+ end
38
45
 
39
46
  # build only the jar file not the whole gem for java platform, the jar is part the concurrent-ruby-x.y.z.gem
40
47
  Rake::Task['lib/concurrent-ruby/concurrent/concurrent_ruby.jar'].invoke
41
48
 
42
49
  # build all gem files
50
+ rack_compiler_dock_kwargs = {}
51
+ if which?('podman') and (!which?('docker') || `docker --version`.include?('podman'))
52
+ # podman and only podman available, so RakeCompilerDock will use podman, otherwise it uses docker
53
+ rack_compiler_dock_kwargs = {
54
+ options: ['--privileged'], # otherwise the directory in the image is empty
55
+ runas: false
56
+ }
57
+ end
43
58
  %w[x86-mingw32 x64-mingw32].each do |plat|
44
- RakeCompilerDock.sh "bundle install --local && bundle exec rake native:#{plat} gem --trace", platform: plat
59
+ RakeCompilerDock.sh(
60
+ "bundle install --local && bundle exec rake native:#{plat} gem --trace",
61
+ platform: plat,
62
+ **rack_compiler_dock_kwargs)
45
63
  end
46
64
  end
47
65
  end
@@ -51,10 +69,13 @@ require 'rubygems'
51
69
  require 'rubygems/package_task'
52
70
 
53
71
  Gem::PackageTask.new(core_gemspec) {} if core_gemspec
54
- Gem::PackageTask.new(ext_gemspec) {} if ext_gemspec && !Concurrent.on_jruby?
72
+ Gem::PackageTask.new(ext_gemspec) {} if ext_gemspec && RUBY_ENGINE != 'jruby'
55
73
  Gem::PackageTask.new(edge_gemspec) {} if edge_gemspec
56
74
 
57
- CLEAN.include('lib/concurrent-ruby/concurrent/2.*', 'lib/concurrent-ruby/concurrent/*.jar')
75
+ CLEAN.include(
76
+ 'lib/concurrent-ruby/concurrent/concurrent_ruby_ext.*',
77
+ 'lib/concurrent-ruby/concurrent/2.*',
78
+ 'lib/concurrent-ruby/concurrent/*.jar')
58
79
 
59
80
  begin
60
81
  require 'rspec'
@@ -74,13 +95,15 @@ begin
74
95
 
75
96
  desc '* test packaged and installed gems instead of local files'
76
97
  task :installed do
77
- Dir.chdir(__dir__) do
78
- sh "gem install pkg/concurrent-ruby-#{Concurrent::VERSION}.gem"
79
- sh "gem install pkg/concurrent-ruby-ext-#{Concurrent::VERSION}.gem" if Concurrent.on_cruby?
80
- sh "gem install pkg/concurrent-ruby-edge-#{Concurrent::EDGE_VERSION}.gem"
81
- ENV['NO_PATH'] = 'true'
82
- sh 'bundle update'
83
- sh 'bundle exec rake spec:ci'
98
+ Bundler.with_original_env do
99
+ Dir.chdir(__dir__) do
100
+ sh "gem install pkg/concurrent-ruby-#{version}.gem"
101
+ sh "gem install pkg/concurrent-ruby-ext-#{version}.gem" if RUBY_ENGINE == 'ruby'
102
+ sh "gem install pkg/concurrent-ruby-edge-#{edge_version}.gem"
103
+ ENV['NO_PATH'] = 'true'
104
+ sh 'bundle update'
105
+ sh 'bundle exec rake spec:ci'
106
+ end
84
107
  end
85
108
  end
86
109
  end
@@ -88,12 +111,25 @@ begin
88
111
  desc 'executed in CI'
89
112
  task :ci => [:compile, 'spec:ci']
90
113
 
114
+ desc 'run each spec file in a separate process to help find missing requires'
115
+ task 'spec:isolated' do
116
+ glob = "#{ENV['DIR'] || 'spec'}/**/*_spec.rb"
117
+ from = ENV['FROM']
118
+ env = { 'ISOLATED' => 'true' }
119
+ Dir[glob].each do |spec|
120
+ next if from and from != spec
121
+ from = nil if from == spec
122
+
123
+ sh env, 'rspec', spec
124
+ end
125
+ end
126
+
91
127
  task :default => [:clobber, :compile, :spec]
92
128
  rescue LoadError => e
93
129
  puts 'RSpec is not installed, skipping test task definitions: ' + e.message
94
130
  end
95
131
 
96
- current_yard_version_name = Concurrent::VERSION
132
+ current_yard_version_name = version
97
133
 
98
134
  begin
99
135
  require 'yard'
@@ -184,34 +220,6 @@ begin
184
220
  *common_yard_options)
185
221
  yard.files = ['no-lib']
186
222
  end
187
-
188
- define_uptodate_task = -> name do
189
- namespace name do
190
- desc "** ensure that #{name} generated documentation is matching the source code"
191
- task :uptodate do
192
- Dir.chdir(__dir__) do
193
- begin
194
- FileUtils.cp_r 'docs', 'docs-copy', verbose: true
195
- Rake::Task["yard:#{name}"].invoke
196
- sh 'diff -r docs/ docs-copy/' do |ok, res|
197
- unless ok
198
- begin
199
- STDOUT.puts "yard:#{name} is not properly generated and committed.", "Continue? (y/n)"
200
- input = STDIN.gets.strip.downcase
201
- end until %w(y n).include?(input)
202
- exit 1 if input == 'n'
203
- end
204
- end
205
- ensure
206
- FileUtils.rm_rf 'docs-copy', verbose: true
207
- end
208
- end
209
- end
210
- end
211
- end
212
-
213
- define_uptodate_task.call current_yard_version_name
214
- define_uptodate_task.call 'master'
215
223
  end
216
224
 
217
225
  rescue LoadError => e
@@ -224,7 +232,9 @@ task :release => ['release:checks', 'release:build', 'release:test', 'release:pu
224
232
  namespace :release do
225
233
  # Depends on environment of @pitr-ch
226
234
 
227
- task :checks => "yard:#{current_yard_version_name}:uptodate" do
235
+ task :checks do
236
+ raise '$CONCURRENT_JRUBY_HOME must be set' unless ENV['CONCURRENT_JRUBY_HOME']
237
+
228
238
  Dir.chdir(__dir__) do
229
239
  sh 'test -z "$(git status --porcelain)"' do |ok, res|
230
240
  unless ok
@@ -255,26 +265,23 @@ namespace :release do
255
265
 
256
266
  desc '* test actual installed gems instead of cloned repository on MRI and JRuby'
257
267
  task :test do
258
- Dir.chdir(__dir__) do
259
- old = ENV['RBENV_VERSION']
268
+ raise '$CONCURRENT_JRUBY_HOME must be set' unless ENV['CONCURRENT_JRUBY_HOME']
260
269
 
261
- mri_version = `ruby -e 'puts RUBY_VERSION'`.chomp
262
- jruby_version = File.basename(ENV['CONCURRENT_JRUBY_HOME'])
263
-
264
- puts "Using following version:"
265
- pp mri_version: mri_version, jruby_version: jruby_version
270
+ Dir.chdir(__dir__) do
271
+ puts "Testing with the installed gem"
266
272
 
267
- ENV['RBENV_VERSION'] = mri_version
268
- sh 'rbenv version'
269
- sh 'bundle exec rake spec:installed'
273
+ Bundler.with_original_env do
274
+ sh 'ruby -v'
275
+ sh 'bundle install'
276
+ sh 'bundle exec rake spec:installed'
270
277
 
271
- ENV['RBENV_VERSION'] = jruby_version
272
- sh 'rbenv version'
273
- sh 'bundle exec rake spec:installed'
278
+ env = { "PATH" => "#{ENV.fetch('CONCURRENT_JRUBY_HOME')}/bin:#{ENV['PATH']}" }
279
+ sh env, 'ruby -v'
280
+ sh env, 'bundle install'
281
+ sh env, 'bundle exec rake spec:installed'
282
+ end
274
283
 
275
284
  puts 'Windows build is untested'
276
-
277
- ENV['RBENV_VERSION'] = old
278
285
  end
279
286
  end
280
287
 
@@ -282,7 +289,8 @@ namespace :release do
282
289
  task :publish => ['publish:ask', 'publish:tag', 'publish:rubygems', 'publish:post_steps']
283
290
 
284
291
  namespace :publish do
285
- publish_edge = false
292
+ publish_base = nil
293
+ publish_edge = nil
286
294
 
287
295
  task :ask do
288
296
  begin
@@ -290,8 +298,15 @@ namespace :release do
290
298
  input = STDIN.gets.strip.downcase
291
299
  end until %w(y n).include?(input)
292
300
  exit 1 if input == 'n'
301
+
302
+ begin
303
+ STDOUT.puts 'Do you want to publish `concurrent-ruby`? (y/n)'
304
+ input = STDIN.gets.strip.downcase
305
+ end until %w(y n).include?(input)
306
+ publish_base = input == 'y'
307
+
293
308
  begin
294
- STDOUT.puts 'It will publish `concurrent-ruby`. Do you want to publish `concurrent-ruby-edge`? (y/n)'
309
+ STDOUT.puts 'Do you want to publish `concurrent-ruby-edge`? (y/n)'
295
310
  input = STDIN.gets.strip.downcase
296
311
  end until %w(y n).include?(input)
297
312
  publish_edge = input == 'y'
@@ -300,30 +315,29 @@ namespace :release do
300
315
  desc '** tag HEAD with current version and push to github'
301
316
  task :tag => :ask do
302
317
  Dir.chdir(__dir__) do
303
- sh "git tag v#{Concurrent::VERSION}"
304
- sh "git push origin v#{Concurrent::VERSION}"
305
- sh "git tag edge-v#{Concurrent::EDGE_VERSION}" if publish_edge
306
- sh "git push origin edge-v#{Concurrent::EDGE_VERSION}" if publish_edge
318
+ sh "git tag v#{version}" if publish_base
319
+ sh "git push origin v#{version}" if publish_base
320
+ sh "git tag edge-v#{edge_version}" if publish_edge
321
+ sh "git push origin edge-v#{edge_version}" if publish_edge
307
322
  end
308
323
  end
309
324
 
310
325
  desc '** push all *.gem files to rubygems'
311
326
  task :rubygems => :ask do
312
327
  Dir.chdir(__dir__) do
313
- sh "gem push pkg/concurrent-ruby-#{Concurrent::VERSION}.gem"
314
- sh "gem push pkg/concurrent-ruby-edge-#{Concurrent::EDGE_VERSION}.gem" if publish_edge
315
- sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}.gem"
316
- sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}-x64-mingw32.gem"
317
- sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}-x86-mingw32.gem"
328
+ sh "gem push pkg/concurrent-ruby-#{version}.gem" if publish_base
329
+ sh "gem push pkg/concurrent-ruby-edge-#{edge_version}.gem" if publish_edge
330
+ sh "gem push pkg/concurrent-ruby-ext-#{version}.gem" if publish_base
331
+ sh "gem push pkg/concurrent-ruby-ext-#{version}-x64-mingw32.gem" if publish_base
332
+ sh "gem push pkg/concurrent-ruby-ext-#{version}-x86-mingw32.gem" if publish_base
318
333
  end
319
334
  end
320
335
 
321
336
  desc '** print post release steps'
322
337
  task :post_steps do
323
- # TODO: (petr 05-Jun-2021) automate and renew the process
324
- # puts 'Manually: create a release on GitHub with relevant changelog part'
325
- # puts 'Manually: send email same as release with relevant changelog part'
326
- # puts 'Manually: tweet'
338
+ puts
339
+ puts 'Manually: create a release on GitHub, use the "Generate release notes" button'
340
+ puts 'Manually: tweet'
327
341
  end
328
342
  end
329
343
  end
@@ -1,12 +1,12 @@
1
1
  package com.concurrent_ruby.ext;
2
2
 
3
+ import static org.jruby.runtime.Visibility.PRIVATE;
4
+
3
5
  import java.lang.reflect.Field;
4
6
  import java.io.IOException;
5
- import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
6
7
  import org.jruby.Ruby;
7
8
  import org.jruby.RubyClass;
8
9
  import org.jruby.RubyModule;
9
- import org.jruby.RubyNumeric;
10
10
  import org.jruby.RubyObject;
11
11
  import org.jruby.anno.JRubyClass;
12
12
  import org.jruby.anno.JRubyMethod;
@@ -91,15 +91,9 @@ public class AtomicReferenceLibrary implements Library {
91
91
  return newValue;
92
92
  }
93
93
 
94
- @JRubyMethod(name = {"compare_and_set", "compare_and_swap"})
94
+ @JRubyMethod(name = "_compare_and_set", visibility = PRIVATE)
95
95
  public IRubyObject compare_and_set(ThreadContext context, IRubyObject expectedValue, IRubyObject newValue) {
96
96
  Ruby runtime = context.runtime;
97
-
98
- if (expectedValue instanceof RubyNumeric) {
99
- // numerics are not always idempotent in Ruby, so we need to do slower logic
100
- return compareAndSetNumeric(context, expectedValue, newValue);
101
- }
102
-
103
97
  return runtime.newBoolean(UNSAFE.compareAndSwapObject(this, referenceOffset, expectedValue, newValue));
104
98
  }
105
99
 
@@ -113,35 +107,6 @@ public class AtomicReferenceLibrary implements Library {
113
107
  }
114
108
  }
115
109
  }
116
-
117
- private IRubyObject compareAndSetNumeric(ThreadContext context, IRubyObject expectedValue, IRubyObject newValue) {
118
- Ruby runtime = context.runtime;
119
-
120
- // loop until:
121
- // * reference CAS would succeed for same-valued objects
122
- // * current and expected have different values as determined by #equals
123
- while (true) {
124
- IRubyObject current = reference;
125
-
126
- if (!(current instanceof RubyNumeric)) {
127
- // old value is not numeric, CAS fails
128
- return runtime.getFalse();
129
- }
130
-
131
- RubyNumeric currentNumber = (RubyNumeric)current;
132
- if (!currentNumber.equals(expectedValue)) {
133
- // current number does not equal expected, fail CAS
134
- return runtime.getFalse();
135
- }
136
-
137
- // check that current has not changed, or else allow loop to repeat
138
- boolean success = UNSAFE.compareAndSwapObject(this, referenceOffset, current, newValue);
139
- if (success) {
140
- // value is same and did not change in interim...success
141
- return runtime.getTrue();
142
- }
143
- }
144
- }
145
110
  }
146
111
 
147
112
  private static final class UnsafeHolder {