concurrent-ruby 1.1.10 → 1.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +47 -1
  3. data/Gemfile +1 -2
  4. data/README.md +23 -20
  5. data/Rakefile +75 -65
  6. data/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java +10 -25
  7. data/lib/concurrent-ruby/concurrent/agent.rb +2 -1
  8. data/lib/concurrent-ruby/concurrent/array.rb +3 -13
  9. data/lib/concurrent-ruby/concurrent/atom.rb +1 -1
  10. data/lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb +5 -4
  11. data/lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb +5 -4
  12. data/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb +3 -0
  13. data/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb +81 -151
  14. data/lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb +1 -1
  15. data/lib/concurrent-ruby/concurrent/atomic/event.rb +1 -1
  16. data/lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb +109 -0
  17. data/lib/concurrent-ruby/concurrent/atomic/java_count_down_latch.rb +1 -0
  18. data/lib/concurrent-ruby/concurrent/atomic/locals.rb +189 -0
  19. data/lib/concurrent-ruby/concurrent/atomic/lock_local_var.rb +28 -0
  20. data/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_boolean.rb +11 -5
  21. data/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_fixnum.rb +11 -5
  22. data/lib/concurrent-ruby/concurrent/atomic/mutex_count_down_latch.rb +1 -1
  23. data/lib/concurrent-ruby/concurrent/atomic/mutex_semaphore.rb +1 -1
  24. data/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb +2 -1
  25. data/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb +5 -3
  26. data/lib/concurrent-ruby/concurrent/atomic/semaphore.rb +6 -9
  27. data/lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb +96 -89
  28. data/lib/concurrent-ruby/concurrent/atomic_reference/atomic_direct_update.rb +37 -0
  29. data/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb +15 -4
  30. data/lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb +1 -1
  31. data/lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb +1 -1
  32. data/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb +2 -0
  33. data/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb +2 -2
  34. data/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb +16 -8
  35. data/lib/concurrent-ruby/concurrent/collection/map/synchronized_map_backend.rb +23 -20
  36. data/lib/concurrent-ruby/concurrent/concern/logging.rb +86 -2
  37. data/lib/concurrent-ruby/concurrent/concurrent_ruby.jar +0 -0
  38. data/lib/concurrent-ruby/concurrent/configuration.rb +4 -87
  39. data/lib/concurrent-ruby/concurrent/delay.rb +2 -2
  40. data/lib/concurrent-ruby/concurrent/errors.rb +5 -0
  41. data/lib/concurrent-ruby/concurrent/exchanger.rb +1 -0
  42. data/lib/concurrent-ruby/concurrent/executor/abstract_executor_service.rb +1 -1
  43. data/lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb +4 -0
  44. data/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb +6 -9
  45. data/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb +5 -0
  46. data/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb +7 -0
  47. data/lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb +1 -1
  48. data/lib/concurrent-ruby/concurrent/executor/serialized_execution.rb +1 -1
  49. data/lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb +4 -1
  50. data/lib/concurrent-ruby/concurrent/executor/timer_set.rb +6 -2
  51. data/lib/concurrent-ruby/concurrent/hash.rb +5 -12
  52. data/lib/concurrent-ruby/concurrent/immutable_struct.rb +1 -1
  53. data/lib/concurrent-ruby/concurrent/ivar.rb +2 -1
  54. data/lib/concurrent-ruby/concurrent/map.rb +43 -39
  55. data/lib/concurrent-ruby/concurrent/maybe.rb +1 -1
  56. data/lib/concurrent-ruby/concurrent/mutable_struct.rb +1 -1
  57. data/lib/concurrent-ruby/concurrent/mvar.rb +1 -1
  58. data/lib/concurrent-ruby/concurrent/promise.rb +1 -1
  59. data/lib/concurrent-ruby/concurrent/promises.rb +40 -29
  60. data/lib/concurrent-ruby/concurrent/re_include.rb +2 -0
  61. data/lib/concurrent-ruby/concurrent/scheduled_task.rb +1 -1
  62. data/lib/concurrent-ruby/concurrent/set.rb +0 -10
  63. data/lib/concurrent-ruby/concurrent/settable_struct.rb +2 -2
  64. data/lib/concurrent-ruby/concurrent/synchronization/abstract_lockable_object.rb +5 -1
  65. data/lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb +1 -3
  66. data/lib/concurrent-ruby/concurrent/synchronization/condition.rb +2 -0
  67. data/lib/concurrent-ruby/concurrent/synchronization/full_memory_barrier.rb +29 -0
  68. data/lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb +3 -1
  69. data/lib/concurrent-ruby/concurrent/synchronization/lock.rb +2 -0
  70. data/lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb +5 -2
  71. data/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb +6 -5
  72. data/lib/concurrent-ruby/concurrent/synchronization/object.rb +12 -44
  73. data/lib/concurrent-ruby/concurrent/synchronization/safe_initialization.rb +36 -0
  74. data/lib/concurrent-ruby/concurrent/synchronization/volatile.rb +77 -12
  75. data/lib/concurrent-ruby/concurrent/synchronization.rb +1 -18
  76. data/lib/concurrent-ruby/concurrent/thread_safe/synchronized_delegator.rb +36 -39
  77. data/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb +1 -37
  78. data/lib/concurrent-ruby/concurrent/timer_task.rb +59 -9
  79. data/lib/concurrent-ruby/concurrent/tuple.rb +1 -5
  80. data/lib/concurrent-ruby/concurrent/tvar.rb +2 -1
  81. data/lib/concurrent-ruby/concurrent/utility/engine.rb +5 -16
  82. data/lib/concurrent-ruby/concurrent/utility/monotonic_time.rb +3 -74
  83. data/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb +8 -10
  84. data/lib/concurrent-ruby/concurrent/utility/native_integer.rb +1 -0
  85. data/lib/concurrent-ruby/concurrent/utility/processor_counter.rb +118 -58
  86. data/lib/concurrent-ruby/concurrent/version.rb +1 -1
  87. metadata +13 -17
  88. data/lib/concurrent-ruby/concurrent/atomic/abstract_thread_local_var.rb +0 -66
  89. data/lib/concurrent-ruby/concurrent/atomic/java_thread_local_var.rb +0 -37
  90. data/lib/concurrent-ruby/concurrent/atomic/ruby_thread_local_var.rb +0 -181
  91. data/lib/concurrent-ruby/concurrent/collection/map/atomic_reference_map_backend.rb +0 -927
  92. data/lib/concurrent-ruby/concurrent/synchronization/jruby_object.rb +0 -45
  93. data/lib/concurrent-ruby/concurrent/synchronization/mri_object.rb +0 -44
  94. data/lib/concurrent-ruby/concurrent/synchronization/rbx_lockable_object.rb +0 -71
  95. data/lib/concurrent-ruby/concurrent/synchronization/rbx_object.rb +0 -49
  96. data/lib/concurrent-ruby/concurrent/synchronization/truffleruby_object.rb +0 -47
  97. 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: 1ca6244c1124d507f5422c42cc9376e46cb2a46f7ad07363731ee0957c410e98
4
+ data.tar.gz: 4c03cbe71e12804bf8d9b0c707895313206a9932be3e182f1674faa70568ca1f
5
5
  SHA512:
6
- metadata.gz: 4c1cbc5311e939aecda5e291bb579a690807de5240bb2fb30600a9d1d9de8c353558de7d6e3e0dff871fcca364bd7caa76b304428e0fdaba323cbe04be300056
7
- data.tar.gz: 863635cad877062864813b9ba72685b3afdadabf258a62b36f8d7093a5be9c7115d64aade01c9a98b9e68ef86dff2698e5e0cef7766b9c4dfc740e0e76eccf0c
6
+ metadata.gz: ceaab8640927f5f0bf5ecde7727705248d5dd5d0a5fe9b4baa8b8d259a2cf0ef9a5e8d636cfacd47588d358ea8c51cd1650f0939be6e3188647553e7158d536f
7
+ data.tar.gz: 216aed72a0d32b40a7e34303751d9c544594b4a51e38e9fd449f3922fcc30fd9a7549d22d7e3d1552b307806ede6c638acffdaded8cd016980a0ae0683b5495e
data/CHANGELOG.md CHANGED
@@ -1,6 +1,52 @@
1
1
  ## Current
2
2
 
3
- ## Release v1.1.10
3
+ ## Release v1.3.3 (9 June 2024)
4
+
5
+ * (#1053) Improve the speed of `Concurrent.physical_processor_count` on Windows.
6
+
7
+ ## Release v1.3.2, edge v0.7.1 (7 June 2024)
8
+
9
+ concurrent-ruby:
10
+
11
+ * (#1051) Remove dependency on `win32ole`.
12
+
13
+ concurrent-ruby-edge:
14
+
15
+ * (#1052) Fix dependency on `concurrent-ruby` to allow the latest release.
16
+
17
+ ## Release v1.3.1 (29 May 2024)
18
+
19
+ * Release 1.3.0 was broken when pushed to RubyGems. 1.3.1 is a packaging fix.
20
+
21
+ ## Release v1.3.0 (28 May 2024)
22
+
23
+ * (#1042) Align Java Executor Service behavior for `shuttingdown?`, `shutdown?`
24
+ * (#1038) Add `Concurrent.available_processor_count` that is cgroups aware.
25
+
26
+ ## Release v1.2.3 (16 Jan 2024)
27
+
28
+ * See [the GitHub release](https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.2.3) for details.
29
+
30
+ ## Release v1.2.2 (24 Feb 2023)
31
+
32
+ * (#993) Fix arguments passed to `Concurrent::Map`'s `default_proc`.
33
+
34
+ ## Release v1.2.1 (24 Feb 2023)
35
+
36
+ * (#990) Add missing `require 'fiber'` for `FiberLocalVar`.
37
+ * (#989) Optimize `Concurrent::Map#[]` on CRuby by letting the backing Hash handle the `default_proc`.
38
+
39
+ ## Release v1.2.0 (23 Jan 2023)
40
+
41
+ * (#962) Fix ReentrantReadWriteLock to use the same granularity for locals as for Mutex it uses.
42
+ * (#983) Add FiberLocalVar
43
+ * (#934) concurrent-ruby now supports requiring individual classes (public classes listed in the docs), e.g., `require 'concurrent/map'`
44
+ * (#976) Let `Promises.any_fulfilled_future` take an `Event`
45
+ * Improve documentation of various classes
46
+ * (#975) Set the Ruby compatibility version at 2.3
47
+ * (#972) Remove Rubinius-related code
48
+
49
+ ## Release v1.1.10 (22 Mar 2022)
4
50
 
5
51
  concurrent-ruby:
6
52
 
data/Gemfile CHANGED
@@ -2,7 +2,6 @@ source 'https://rubygems.org'
2
2
 
3
3
  require File.join(File.dirname(__FILE__), 'lib/concurrent-ruby/concurrent/version')
4
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')
6
5
 
7
6
  no_path = ENV['NO_PATH']
8
7
  options = no_path ? {} : { path: '.' }
@@ -13,7 +12,7 @@ gem 'concurrent-ruby-ext', Concurrent::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
 
@@ -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
 
@@ -362,20 +364,20 @@ best practice is to depend on `concurrent-ruby` and let users to decide if they
362
364
 
363
365
  * Update `version.rb`
364
366
  * 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.
367
+ * Add the new version to `docs-source/signpost.md`. Needs to be done only if there are visible changes in the documentation.
370
368
  * 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.
369
+ * Use `bundle exec rake release` to release the gem.
370
+ It consists of `['release:checks', 'release:build', 'release:test', 'release:publish']` steps.
371
+ It will ask at the end before publishing anything. Steps can also be executed individually.
374
372
 
375
373
  ## Maintainers
376
374
 
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.
375
+ * [Benoit Daloze](https://github.com/eregon)
376
+ * [Matthew Draper](https://github.com/matthewd)
377
+ * [Rafael França](https://github.com/rafaelfranca)
378
+ * [Charles Oliver Nutter](https://github.com/headius)
379
+ * [Ben Sheldon](https://github.com/bensheldon)
380
+ * [Samuel Williams](https://github.com/ioquatix)
379
381
 
380
382
  ### Special Thanks to
381
383
 
@@ -386,6 +388,7 @@ best practice is to depend on `concurrent-ruby` and let users to decide if they
386
388
 
387
389
  to the past maintainers
388
390
 
391
+ * [Chris Seaton](https://github.com/chrisseaton)
389
392
  * [Petr Chalupa](https://github.com/pitr-ch)
390
393
  * [Michele Della Torre](https://github.com/mighe)
391
394
  * [Paweł Obrok](https://github.com/obrok)
data/Rakefile CHANGED
@@ -28,20 +28,37 @@ unless Concurrent.on_jruby? || Concurrent.on_truffleruby?
28
28
  end
29
29
  end
30
30
 
31
+ def which?(executable)
32
+ !`which #{executable} 2>/dev/null`.empty?
33
+ end
34
+
31
35
  require 'rake_compiler_dock'
32
36
  namespace :repackage do
33
37
  desc '* with Windows fat distributions'
34
38
  task :all do
35
39
  Dir.chdir(__dir__) do
36
40
  # store gems in vendor cache for docker
37
- sh 'bundle package'
41
+ Bundler.with_original_env do
42
+ sh 'bundle package'
43
+ end
38
44
 
39
45
  # build only the jar file not the whole gem for java platform, the jar is part the concurrent-ruby-x.y.z.gem
40
46
  Rake::Task['lib/concurrent-ruby/concurrent/concurrent_ruby.jar'].invoke
41
47
 
42
48
  # build all gem files
49
+ rack_compiler_dock_kwargs = {}
50
+ if which?('podman') and (!which?('docker') || `docker --version`.include?('podman'))
51
+ # podman and only podman available, so RakeCompilerDock will use podman, otherwise it uses docker
52
+ rack_compiler_dock_kwargs = {
53
+ options: ['--privileged'], # otherwise the directory in the image is empty
54
+ runas: false
55
+ }
56
+ end
43
57
  %w[x86-mingw32 x64-mingw32].each do |plat|
44
- RakeCompilerDock.sh "bundle install --local && bundle exec rake native:#{plat} gem --trace", platform: plat
58
+ RakeCompilerDock.sh(
59
+ "bundle install --local && bundle exec rake native:#{plat} gem --trace",
60
+ platform: plat,
61
+ **rack_compiler_dock_kwargs)
45
62
  end
46
63
  end
47
64
  end
@@ -54,7 +71,10 @@ Gem::PackageTask.new(core_gemspec) {} if core_gemspec
54
71
  Gem::PackageTask.new(ext_gemspec) {} if ext_gemspec && !Concurrent.on_jruby?
55
72
  Gem::PackageTask.new(edge_gemspec) {} if edge_gemspec
56
73
 
57
- CLEAN.include('lib/concurrent-ruby/concurrent/2.*', 'lib/concurrent-ruby/concurrent/*.jar')
74
+ CLEAN.include(
75
+ 'lib/concurrent-ruby/concurrent/concurrent_ruby_ext.*',
76
+ 'lib/concurrent-ruby/concurrent/2.*',
77
+ 'lib/concurrent-ruby/concurrent/*.jar')
58
78
 
59
79
  begin
60
80
  require 'rspec'
@@ -74,13 +94,15 @@ begin
74
94
 
75
95
  desc '* test packaged and installed gems instead of local files'
76
96
  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'
97
+ Bundler.with_original_env do
98
+ Dir.chdir(__dir__) do
99
+ sh "gem install pkg/concurrent-ruby-#{Concurrent::VERSION}.gem"
100
+ sh "gem install pkg/concurrent-ruby-ext-#{Concurrent::VERSION}.gem" if Concurrent.on_cruby?
101
+ sh "gem install pkg/concurrent-ruby-edge-#{Concurrent::EDGE_VERSION}.gem"
102
+ ENV['NO_PATH'] = 'true'
103
+ sh 'bundle update'
104
+ sh 'bundle exec rake spec:ci'
105
+ end
84
106
  end
85
107
  end
86
108
  end
@@ -88,6 +110,19 @@ begin
88
110
  desc 'executed in CI'
89
111
  task :ci => [:compile, 'spec:ci']
90
112
 
113
+ desc 'run each spec file in a separate process to help find missing requires'
114
+ task 'spec:isolated' do
115
+ glob = "#{ENV['DIR'] || 'spec'}/**/*_spec.rb"
116
+ from = ENV['FROM']
117
+ env = { 'ISOLATED' => 'true' }
118
+ Dir[glob].each do |spec|
119
+ next if from and from != spec
120
+ from = nil if from == spec
121
+
122
+ sh env, 'rspec', spec
123
+ end
124
+ end
125
+
91
126
  task :default => [:clobber, :compile, :spec]
92
127
  rescue LoadError => e
93
128
  puts 'RSpec is not installed, skipping test task definitions: ' + e.message
@@ -184,34 +219,6 @@ begin
184
219
  *common_yard_options)
185
220
  yard.files = ['no-lib']
186
221
  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
222
  end
216
223
 
217
224
  rescue LoadError => e
@@ -224,7 +231,7 @@ task :release => ['release:checks', 'release:build', 'release:test', 'release:pu
224
231
  namespace :release do
225
232
  # Depends on environment of @pitr-ch
226
233
 
227
- task :checks => "yard:#{current_yard_version_name}:uptodate" do
234
+ task :checks do
228
235
  Dir.chdir(__dir__) do
229
236
  sh 'test -z "$(git status --porcelain)"' do |ok, res|
230
237
  unless ok
@@ -256,25 +263,20 @@ namespace :release do
256
263
  desc '* test actual installed gems instead of cloned repository on MRI and JRuby'
257
264
  task :test do
258
265
  Dir.chdir(__dir__) do
259
- old = ENV['RBENV_VERSION']
266
+ puts "Testing with the installed gem"
260
267
 
261
- mri_version = `ruby -e 'puts RUBY_VERSION'`.chomp
262
- jruby_version = File.basename(ENV['CONCURRENT_JRUBY_HOME'])
268
+ Bundler.with_original_env do
269
+ sh 'ruby -v'
270
+ sh 'bundle install'
271
+ sh 'bundle exec rake spec:installed'
263
272
 
264
- puts "Using following version:"
265
- pp mri_version: mri_version, jruby_version: jruby_version
266
-
267
- ENV['RBENV_VERSION'] = mri_version
268
- sh 'rbenv version'
269
- sh 'bundle exec rake spec:installed'
270
-
271
- ENV['RBENV_VERSION'] = jruby_version
272
- sh 'rbenv version'
273
- sh 'bundle exec rake spec:installed'
273
+ env = { "PATH" => "#{ENV.fetch('CONCURRENT_JRUBY_HOME')}/bin:#{ENV['PATH']}" }
274
+ sh env, 'ruby -v'
275
+ sh env, 'bundle install'
276
+ sh env, 'bundle exec rake spec:installed'
277
+ end
274
278
 
275
279
  puts 'Windows build is untested'
276
-
277
- ENV['RBENV_VERSION'] = old
278
280
  end
279
281
  end
280
282
 
@@ -282,7 +284,8 @@ namespace :release do
282
284
  task :publish => ['publish:ask', 'publish:tag', 'publish:rubygems', 'publish:post_steps']
283
285
 
284
286
  namespace :publish do
285
- publish_edge = false
287
+ publish_base = nil
288
+ publish_edge = nil
286
289
 
287
290
  task :ask do
288
291
  begin
@@ -290,8 +293,15 @@ namespace :release do
290
293
  input = STDIN.gets.strip.downcase
291
294
  end until %w(y n).include?(input)
292
295
  exit 1 if input == 'n'
296
+
297
+ begin
298
+ STDOUT.puts 'Do you want to publish `concurrent-ruby`? (y/n)'
299
+ input = STDIN.gets.strip.downcase
300
+ end until %w(y n).include?(input)
301
+ publish_base = input == 'y'
302
+
293
303
  begin
294
- STDOUT.puts 'It will publish `concurrent-ruby`. Do you want to publish `concurrent-ruby-edge`? (y/n)'
304
+ STDOUT.puts 'Do you want to publish `concurrent-ruby-edge`? (y/n)'
295
305
  input = STDIN.gets.strip.downcase
296
306
  end until %w(y n).include?(input)
297
307
  publish_edge = input == 'y'
@@ -300,8 +310,8 @@ namespace :release do
300
310
  desc '** tag HEAD with current version and push to github'
301
311
  task :tag => :ask do
302
312
  Dir.chdir(__dir__) do
303
- sh "git tag v#{Concurrent::VERSION}"
304
- sh "git push origin v#{Concurrent::VERSION}"
313
+ sh "git tag v#{Concurrent::VERSION}" if publish_base
314
+ sh "git push origin v#{Concurrent::VERSION}" if publish_base
305
315
  sh "git tag edge-v#{Concurrent::EDGE_VERSION}" if publish_edge
306
316
  sh "git push origin edge-v#{Concurrent::EDGE_VERSION}" if publish_edge
307
317
  end
@@ -310,20 +320,20 @@ namespace :release do
310
320
  desc '** push all *.gem files to rubygems'
311
321
  task :rubygems => :ask do
312
322
  Dir.chdir(__dir__) do
313
- sh "gem push pkg/concurrent-ruby-#{Concurrent::VERSION}.gem"
323
+ sh "gem push pkg/concurrent-ruby-#{Concurrent::VERSION}.gem" if publish_base
314
324
  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"
325
+ sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}.gem" if publish_base
326
+ sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}-x64-mingw32.gem" if publish_base
327
+ sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}-x86-mingw32.gem" if publish_base
318
328
  end
319
329
  end
320
330
 
321
331
  desc '** print post release steps'
322
332
  task :post_steps do
323
333
  # 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'
334
+ puts 'Manually: create a release on GitHub with relevant changelog part'
335
+ puts 'Manually: send email same as release with relevant changelog part'
336
+ puts 'Manually: tweet'
327
337
  end
328
338
  end
329
339
  end
@@ -55,12 +55,6 @@ public class SynchronizationLibrary implements Library {
55
55
  }
56
56
  }
57
57
 
58
- private static final ObjectAllocator JRUBY_OBJECT_ALLOCATOR = new ObjectAllocator() {
59
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
60
- return new JRubyObject(runtime, klazz);
61
- }
62
- };
63
-
64
58
  private static final ObjectAllocator OBJECT_ALLOCATOR = new ObjectAllocator() {
65
59
  public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
66
60
  return new Object(runtime, klazz);
@@ -87,10 +81,7 @@ public class SynchronizationLibrary implements Library {
87
81
  RubyModule jrubyAttrVolatileModule = synchronizationModule.defineModuleUnder("JRubyAttrVolatile");
88
82
  jrubyAttrVolatileModule.defineAnnotatedMethods(JRubyAttrVolatile.class);
89
83
 
90
- defineClass(runtime, synchronizationModule, "AbstractObject", "JRubyObject",
91
- JRubyObject.class, JRUBY_OBJECT_ALLOCATOR);
92
-
93
- defineClass(runtime, synchronizationModule, "JRubyObject", "Object",
84
+ defineClass(runtime, synchronizationModule, "AbstractObject", "Object",
94
85
  Object.class, OBJECT_ALLOCATOR);
95
86
 
96
87
  defineClass(runtime, synchronizationModule, "Object", "AbstractLockableObject",
@@ -143,8 +134,8 @@ public class SynchronizationLibrary implements Library {
143
134
  // attempt to avoid code elimination.
144
135
  private static volatile int volatileField;
145
136
 
146
- @JRubyMethod(name = "full_memory_barrier", visibility = Visibility.PUBLIC)
147
- public static IRubyObject fullMemoryBarrier(ThreadContext context, IRubyObject self) {
137
+ @JRubyMethod(name = "full_memory_barrier", visibility = Visibility.PUBLIC, module = true)
138
+ public static IRubyObject fullMemoryBarrier(ThreadContext context, IRubyObject module) {
148
139
  // Prevent reordering of ivar writes with publication of this instance
149
140
  if (!FULL_FENCE) {
150
141
  // Assuming that following volatile read and write is not eliminated it simulates fullFence.
@@ -158,9 +149,10 @@ public class SynchronizationLibrary implements Library {
158
149
  return context.nil;
159
150
  }
160
151
 
161
- @JRubyMethod(name = "instance_variable_get_volatile", visibility = Visibility.PUBLIC)
152
+ @JRubyMethod(name = "instance_variable_get_volatile", visibility = Visibility.PUBLIC, module = true)
162
153
  public static IRubyObject instanceVariableGetVolatile(
163
154
  ThreadContext context,
155
+ IRubyObject module,
164
156
  IRubyObject self,
165
157
  IRubyObject name) {
166
158
  // Ensure we ses latest value with loadFence
@@ -174,9 +166,10 @@ public class SynchronizationLibrary implements Library {
174
166
  }
175
167
  }
176
168
 
177
- @JRubyMethod(name = "instance_variable_set_volatile", visibility = Visibility.PUBLIC)
169
+ @JRubyMethod(name = "instance_variable_set_volatile", visibility = Visibility.PUBLIC, module = true)
178
170
  public static IRubyObject InstanceVariableSetVolatile(
179
171
  ThreadContext context,
172
+ IRubyObject module,
180
173
  IRubyObject self,
181
174
  IRubyObject name,
182
175
  IRubyObject value) {
@@ -195,16 +188,8 @@ public class SynchronizationLibrary implements Library {
195
188
  }
196
189
  }
197
190
 
198
- @JRubyClass(name = "JRubyObject", parent = "AbstractObject")
199
- public static class JRubyObject extends RubyObject {
200
-
201
- public JRubyObject(Ruby runtime, RubyClass metaClass) {
202
- super(runtime, metaClass);
203
- }
204
- }
205
-
206
- @JRubyClass(name = "Object", parent = "JRubyObject")
207
- public static class Object extends JRubyObject {
191
+ @JRubyClass(name = "Object", parent = "AbstractObject")
192
+ public static class Object extends RubyObject {
208
193
 
209
194
  public Object(Ruby runtime, RubyClass metaClass) {
210
195
  super(runtime, metaClass);
@@ -220,7 +205,7 @@ public class SynchronizationLibrary implements Library {
220
205
  }
221
206
 
222
207
  @JRubyClass(name = "JRubyLockableObject", parent = "AbstractLockableObject")
223
- public static class JRubyLockableObject extends JRubyObject {
208
+ public static class JRubyLockableObject extends AbstractLockableObject {
224
209
 
225
210
  public JRubyLockableObject(Ruby runtime, RubyClass metaClass) {
226
211
  super(runtime, metaClass);
@@ -1,9 +1,10 @@
1
1
  require 'concurrent/configuration'
2
2
  require 'concurrent/atomic/atomic_reference'
3
+ require 'concurrent/atomic/count_down_latch'
3
4
  require 'concurrent/atomic/thread_local_var'
4
5
  require 'concurrent/collection/copy_on_write_observer_set'
5
6
  require 'concurrent/concern/observable'
6
- require 'concurrent/synchronization'
7
+ require 'concurrent/synchronization/lockable_object'
7
8
 
8
9
  module Concurrent
9
10
 
@@ -21,9 +21,9 @@ module Concurrent
21
21
  # @!macro internal_implementation_note
22
22
  ArrayImplementation = case
23
23
  when Concurrent.on_cruby?
24
- # Array is thread-safe in practice because CRuby runs
25
- # threads one at a time and does not do context
26
- # switching during the execution of C functions.
24
+ # Array is not fully thread-safe on CRuby, see
25
+ # https://github.com/ruby-concurrency/concurrent-ruby/issues/929
26
+ # So we will need to add synchronization here
27
27
  ::Array
28
28
 
29
29
  when Concurrent.on_jruby?
@@ -34,16 +34,6 @@ module Concurrent
34
34
  end
35
35
  JRubyArray
36
36
 
37
- when Concurrent.on_rbx?
38
- require 'monitor'
39
- require 'concurrent/thread_safe/util/data_structures'
40
-
41
- class RbxArray < ::Array
42
- end
43
-
44
- ThreadSafe::Util.make_synchronized_on_rbx RbxArray
45
- RbxArray
46
-
47
37
  when Concurrent.on_truffleruby?
48
38
  require 'concurrent/thread_safe/util/data_structures'
49
39
 
@@ -1,7 +1,7 @@
1
1
  require 'concurrent/atomic/atomic_reference'
2
2
  require 'concurrent/collection/copy_on_notify_observer_set'
3
3
  require 'concurrent/concern/observable'
4
- require 'concurrent/synchronization'
4
+ require 'concurrent/synchronization/object'
5
5
 
6
6
  # @!macro thread_safe_variable_comparison
7
7
  #
@@ -1,5 +1,6 @@
1
+ require 'concurrent/utility/native_extension_loader' # load native parts first
2
+
1
3
  require 'concurrent/atomic/mutex_atomic_boolean'
2
- require 'concurrent/synchronization'
3
4
 
4
5
  module Concurrent
5
6
 
@@ -79,10 +80,10 @@ module Concurrent
79
80
  # @!visibility private
80
81
  # @!macro internal_implementation_note
81
82
  AtomicBooleanImplementation = case
82
- when defined?(JavaAtomicBoolean)
83
- JavaAtomicBoolean
84
- when defined?(CAtomicBoolean)
83
+ when Concurrent.on_cruby? && Concurrent.c_extensions_loaded?
85
84
  CAtomicBoolean
85
+ when Concurrent.on_jruby?
86
+ JavaAtomicBoolean
86
87
  else
87
88
  MutexAtomicBoolean
88
89
  end
@@ -1,5 +1,6 @@
1
+ require 'concurrent/utility/native_extension_loader' # load native parts first
2
+
1
3
  require 'concurrent/atomic/mutex_atomic_fixnum'
2
- require 'concurrent/synchronization'
3
4
 
4
5
  module Concurrent
5
6
 
@@ -96,10 +97,10 @@ module Concurrent
96
97
  # @!visibility private
97
98
  # @!macro internal_implementation_note
98
99
  AtomicFixnumImplementation = case
99
- when defined?(JavaAtomicFixnum)
100
- JavaAtomicFixnum
101
- when defined?(CAtomicFixnum)
100
+ when Concurrent.on_cruby? && Concurrent.c_extensions_loaded?
102
101
  CAtomicFixnum
102
+ when Concurrent.on_jruby?
103
+ JavaAtomicFixnum
103
104
  else
104
105
  MutexAtomicFixnum
105
106
  end
@@ -1,3 +1,6 @@
1
+ require 'concurrent/errors'
2
+ require 'concurrent/synchronization/object'
3
+
1
4
  module Concurrent
2
5
  # An atomic reference which maintains an object reference along with a mark bit
3
6
  # that can be updated atomically.