concurrent-ruby 1.1.5 → 1.1.6

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 (128) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -1
  3. data/Gemfile +4 -3
  4. data/README.md +3 -0
  5. data/Rakefile +16 -11
  6. data/lib/{concurrent → concurrent-ruby/concurrent}/agent.rb +0 -0
  7. data/lib/{concurrent → concurrent-ruby/concurrent}/array.rb +5 -5
  8. data/lib/{concurrent → concurrent-ruby/concurrent}/async.rb +0 -0
  9. data/lib/{concurrent → concurrent-ruby/concurrent}/atom.rb +1 -1
  10. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/abstract_thread_local_var.rb +0 -0
  11. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_boolean.rb +2 -2
  12. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_fixnum.rb +0 -0
  13. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_markable_reference.rb +0 -0
  14. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_reference.rb +0 -0
  15. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/count_down_latch.rb +1 -1
  16. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/cyclic_barrier.rb +0 -0
  17. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/event.rb +0 -0
  18. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/java_count_down_latch.rb +0 -0
  19. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/java_thread_local_var.rb +0 -0
  20. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_atomic_boolean.rb +0 -0
  21. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_atomic_fixnum.rb +0 -0
  22. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_count_down_latch.rb +0 -0
  23. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_semaphore.rb +0 -0
  24. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/read_write_lock.rb +0 -0
  25. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/reentrant_read_write_lock.rb +0 -0
  26. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/ruby_thread_local_var.rb +43 -33
  27. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/semaphore.rb +0 -0
  28. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/thread_local_var.rb +1 -1
  29. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic_reference/mutex_atomic.rb +0 -0
  30. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic_reference/numeric_cas_wrapper.rb +0 -0
  31. data/lib/{concurrent → concurrent-ruby/concurrent}/atomics.rb +0 -0
  32. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/copy_on_notify_observer_set.rb +0 -0
  33. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/copy_on_write_observer_set.rb +0 -0
  34. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/java_non_concurrent_priority_queue.rb +0 -0
  35. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/lock_free_stack.rb +0 -0
  36. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/atomic_reference_map_backend.rb +0 -0
  37. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/mri_map_backend.rb +0 -0
  38. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/non_concurrent_map_backend.rb +0 -0
  39. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/synchronized_map_backend.rb +0 -0
  40. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/non_concurrent_priority_queue.rb +1 -1
  41. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/ruby_non_concurrent_priority_queue.rb +0 -0
  42. data/lib/{concurrent → concurrent-ruby/concurrent}/concern/deprecation.rb +0 -0
  43. data/lib/{concurrent → concurrent-ruby/concurrent}/concern/dereferenceable.rb +2 -2
  44. data/lib/{concurrent → concurrent-ruby/concurrent}/concern/logging.rb +0 -0
  45. data/lib/{concurrent → concurrent-ruby/concurrent}/concern/obligation.rb +0 -0
  46. data/lib/{concurrent → concurrent-ruby/concurrent}/concern/observable.rb +0 -0
  47. data/lib/{concurrent → concurrent-ruby/concurrent}/concurrent_ruby.jar +0 -0
  48. data/lib/{concurrent → concurrent-ruby/concurrent}/configuration.rb +13 -9
  49. data/lib/{concurrent → concurrent-ruby/concurrent}/constants.rb +0 -0
  50. data/lib/{concurrent → concurrent-ruby/concurrent}/dataflow.rb +0 -0
  51. data/lib/{concurrent → concurrent-ruby/concurrent}/delay.rb +0 -0
  52. data/lib/{concurrent → concurrent-ruby/concurrent}/errors.rb +0 -0
  53. data/lib/{concurrent → concurrent-ruby/concurrent}/exchanger.rb +0 -0
  54. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/abstract_executor_service.rb +17 -23
  55. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/cached_thread_pool.rb +4 -4
  56. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/executor_service.rb +2 -2
  57. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/fixed_thread_pool.rb +9 -12
  58. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/immediate_executor.rb +0 -0
  59. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/indirect_immediate_executor.rb +0 -0
  60. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/java_executor_service.rb +18 -6
  61. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/java_single_thread_executor.rb +4 -3
  62. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/java_thread_pool_executor.rb +2 -1
  63. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/ruby_executor_service.rb +0 -2
  64. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/ruby_single_thread_executor.rb +0 -1
  65. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/ruby_thread_pool_executor.rb +9 -4
  66. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/safe_task_executor.rb +0 -0
  67. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/serial_executor_service.rb +0 -0
  68. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/serialized_execution.rb +0 -0
  69. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/serialized_execution_delegator.rb +0 -0
  70. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/simple_executor_service.rb +1 -1
  71. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/single_thread_executor.rb +1 -0
  72. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/thread_pool_executor.rb +0 -0
  73. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/timer_set.rb +0 -1
  74. data/lib/{concurrent → concurrent-ruby/concurrent}/executors.rb +0 -0
  75. data/lib/{concurrent → concurrent-ruby/concurrent}/future.rb +0 -0
  76. data/lib/{concurrent → concurrent-ruby/concurrent}/hash.rb +0 -0
  77. data/lib/{concurrent → concurrent-ruby/concurrent}/immutable_struct.rb +8 -0
  78. data/lib/{concurrent → concurrent-ruby/concurrent}/ivar.rb +0 -0
  79. data/lib/{concurrent → concurrent-ruby/concurrent}/map.rb +1 -1
  80. data/lib/{concurrent → concurrent-ruby/concurrent}/maybe.rb +0 -0
  81. data/lib/{concurrent → concurrent-ruby/concurrent}/mutable_struct.rb +10 -0
  82. data/lib/{concurrent → concurrent-ruby/concurrent}/mvar.rb +0 -0
  83. data/lib/{concurrent → concurrent-ruby/concurrent}/options.rb +0 -0
  84. data/lib/{concurrent → concurrent-ruby/concurrent}/promise.rb +0 -0
  85. data/lib/{concurrent → concurrent-ruby/concurrent}/promises.rb +0 -0
  86. data/lib/{concurrent → concurrent-ruby/concurrent}/re_include.rb +0 -0
  87. data/lib/{concurrent → concurrent-ruby/concurrent}/scheduled_task.rb +0 -0
  88. data/lib/{concurrent → concurrent-ruby/concurrent}/set.rb +5 -5
  89. data/lib/{concurrent → concurrent-ruby/concurrent}/settable_struct.rb +10 -0
  90. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/abstract_lockable_object.rb +0 -0
  91. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/abstract_object.rb +0 -0
  92. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/abstract_struct.rb +11 -0
  93. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/condition.rb +0 -0
  94. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/jruby_lockable_object.rb +0 -0
  95. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/jruby_object.rb +0 -0
  96. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/lock.rb +0 -0
  97. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/lockable_object.rb +0 -0
  98. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/mri_object.rb +0 -0
  99. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/mutex_lockable_object.rb +0 -0
  100. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/object.rb +0 -0
  101. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/rbx_lockable_object.rb +0 -0
  102. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/rbx_object.rb +0 -0
  103. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/truffleruby_object.rb +0 -0
  104. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/volatile.rb +0 -0
  105. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization.rb +0 -0
  106. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/synchronized_delegator.rb +0 -0
  107. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/adder.rb +0 -0
  108. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/cheap_lockable.rb +0 -0
  109. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/data_structures.rb +0 -0
  110. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/power_of_two_tuple.rb +0 -0
  111. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/striped64.rb +0 -0
  112. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/volatile.rb +0 -0
  113. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/xor_shift_random.rb +0 -0
  114. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util.rb +0 -0
  115. data/lib/{concurrent → concurrent-ruby/concurrent}/timer_task.rb +0 -0
  116. data/lib/{concurrent → concurrent-ruby/concurrent}/tuple.rb +0 -0
  117. data/lib/{concurrent → concurrent-ruby/concurrent}/tvar.rb +0 -0
  118. data/lib/{concurrent → concurrent-ruby/concurrent}/utility/engine.rb +0 -0
  119. data/lib/{concurrent → concurrent-ruby/concurrent}/utility/monotonic_time.rb +0 -0
  120. data/lib/{concurrent → concurrent-ruby/concurrent}/utility/native_extension_loader.rb +0 -0
  121. data/lib/{concurrent → concurrent-ruby/concurrent}/utility/native_integer.rb +0 -0
  122. data/lib/{concurrent → concurrent-ruby/concurrent}/utility/processor_counter.rb +5 -0
  123. data/lib/concurrent-ruby/concurrent/version.rb +3 -0
  124. data/lib/{concurrent-ruby.rb → concurrent-ruby/concurrent-ruby.rb} +0 -0
  125. data/lib/{concurrent.rb → concurrent-ruby/concurrent.rb} +0 -0
  126. metadata +125 -125
  127. data/lib/concurrent/utility/at_exit.rb +0 -97
  128. data/lib/concurrent/version.rb +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 96f32c31090c8a0547e4ee452739bdc993aad1256e2c89cb9a46d7f7e7b5762a
4
- data.tar.gz: 307d26bde3add56b7e2b37fb0b016c7726a3ba0755dcfec8202fb0760e4ac485
3
+ metadata.gz: 649de1a5e5c7c82652bd6ad21496f2c1061d7c75517271d8ca30c3ceb9c49038
4
+ data.tar.gz: 6274d2cd2dcda660a1e34436547eca26d6c74d03e9a527d7ce5d1a9f3f72f4be
5
5
  SHA512:
6
- metadata.gz: b8cff93c6ef396aebbe5cf69734d9a91f0351e24b5c1846ae105b055254f972cd9d6bb99b90ce10d387627ed43c4e21db9ce47d1587e10278e80e33a53f8d4c4
7
- data.tar.gz: f367f097759eedb8e18b0117543176c9f30ab29552888fcedab0baaea355cee3d100d2559dd16cf54483778545097f8b3340bebe44b0e3ab2a51c1af3830f5e1
6
+ metadata.gz: 2adbf28bdf7034295709496964e8e70d22f59bf058bf18ca005c2ce536627160538de6c510ea1f39893de0ad90b2fb50d6f35c848c97f58bd8f71ff8d9e57fc2
7
+ data.tar.gz: 1cbc384488e0f70d19d742e54c34dbd7abfaffe89f75230b2f5b80d2ae4d161b731666ce6b64e8f5adeb561b6d32191ce6bd679e05d6bd9eec91b869ee379b2f
data/CHANGELOG.md CHANGED
@@ -1,6 +1,30 @@
1
1
  ## Current
2
2
 
3
- ## Release v1.1.5, edge v0.5.0 (10 mar 2019)
3
+ ## Release v1.1.6, edge v0.6.0 (10 Feb 2020)
4
+
5
+ concurrent-ruby:
6
+
7
+ * (#841) Concurrent.disable_at_exit_handlers! is no longer needed and was deprecated.
8
+ * (#841) AbstractExecutorService#auto_terminate= was deprecated and has no effect.
9
+ Set :auto_terminate option instead when executor is initialized.
10
+
11
+ ## Release v1.1.6.pre1, edge v0.6.0.pre1 (26 Jan 2020)
12
+
13
+ concurrent-ruby:
14
+
15
+ * (#828) Allow to name executors, the name is also used to name their threads
16
+ * (#838) Implement #dup and #clone for structs
17
+ * (#821) Safer finalizers for thread local variables
18
+ * Documentation fixes
19
+ * (#814) Use Ruby's Etc.nprocessors if available
20
+ * (#812) Fix directory structure not to mess with packaging tools
21
+ * (#840) Fix termination of pools on JRuby
22
+
23
+ concurrent-ruby-edge:
24
+
25
+ * Add WrappingExecutor (#830)
26
+
27
+ ## Release v1.1.5, edge v0.5.0 (10 Mar 2019)
4
28
 
5
29
  concurrent-ruby:
6
30
 
data/Gemfile CHANGED
@@ -1,7 +1,8 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- require File.join(File.dirname(__FILE__), 'lib/concurrent/version')
4
- require File.join(File.dirname(__FILE__ ), 'lib-edge/concurrent/edge/version')
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')
5
6
 
6
7
  no_path = ENV['NO_PATH']
7
8
  options = no_path ? {} : { path: '.' }
@@ -11,7 +12,7 @@ gem 'concurrent-ruby-edge', Concurrent::EDGE_VERSION, options
11
12
  gem 'concurrent-ruby-ext', Concurrent::VERSION, options.merge(platform: :mri)
12
13
 
13
14
  group :development do
14
- gem 'rake', '~> 12.0'
15
+ gem 'rake', (Concurrent.ruby_version :<, 2, 2, 0) ? '~> 12.0' : '~> 13.0'
15
16
  gem 'rake-compiler', '~> 1.0', '>= 1.0.7'
16
17
  gem 'rake-compiler-dock', '~> 0.7.0'
17
18
  gem 'pry', '~> 0.11', platforms: :mri
data/README.md CHANGED
@@ -253,6 +253,9 @@ be obeyed though. Features developed in `concurrent-ruby-edge` are expected to m
253
253
  * [ErlangActor](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ErlangActor.html)
254
254
  Actor implementation which precisely matches Erlang actor behaviour.
255
255
  Requires at least Ruby 2.1 otherwise it's not loaded.
256
+ * [WrappingExecutor](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/WrappingExecutor.html)
257
+ A delegating executor which modifies each task before the task is given to
258
+ the target executor it delegates to.
256
259
 
257
260
  ## Supported Ruby versions
258
261
 
data/Rakefile CHANGED
@@ -1,5 +1,6 @@
1
- require_relative 'lib/concurrent/version'
2
- require_relative 'lib/concurrent/utility/engine'
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'
3
4
 
4
5
  if Concurrent.ruby_version :<, 2, 0, 0
5
6
  # @!visibility private
@@ -16,9 +17,11 @@ edge_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby-edge.
16
17
 
17
18
  require 'rake/javaextensiontask'
18
19
 
20
+ ENV['JRUBY_HOME'] = ENV['CONCURRENT_JRUBY_HOME'] if ENV['CONCURRENT_JRUBY_HOME'] && !Concurrent.on_jruby?
21
+
19
22
  Rake::JavaExtensionTask.new('concurrent_ruby', core_gemspec) do |ext|
20
23
  ext.ext_dir = 'ext/concurrent-ruby'
21
- ext.lib_dir = 'lib/concurrent'
24
+ ext.lib_dir = 'lib/concurrent-ruby/concurrent'
22
25
  end
23
26
 
24
27
  unless Concurrent.on_jruby?
@@ -26,7 +29,7 @@ unless Concurrent.on_jruby?
26
29
 
27
30
  Rake::ExtensionTask.new('concurrent_ruby_ext', ext_gemspec) do |ext|
28
31
  ext.ext_dir = 'ext/concurrent-ruby-ext'
29
- ext.lib_dir = 'lib/concurrent'
32
+ ext.lib_dir = 'lib/concurrent-ruby/concurrent'
30
33
  ext.source_pattern = '*.{c,h}'
31
34
 
32
35
  ext.cross_compile = true
@@ -43,7 +46,7 @@ namespace :repackage do
43
46
  sh 'bundle package'
44
47
 
45
48
  # build only the jar file not the whole gem for java platform, the jar is part the concurrent-ruby-x.y.z.gem
46
- Rake::Task['lib/concurrent/concurrent_ruby.jar'].invoke
49
+ Rake::Task['lib/concurrent-ruby/concurrent/concurrent_ruby.jar'].invoke
47
50
 
48
51
  # build all gem files
49
52
  RakeCompilerDock.sh 'bundle install --local && bundle exec rake cross native package --trace'
@@ -58,7 +61,7 @@ Gem::PackageTask.new(core_gemspec) {} if core_gemspec
58
61
  Gem::PackageTask.new(ext_gemspec) {} if ext_gemspec && !Concurrent.on_jruby?
59
62
  Gem::PackageTask.new(edge_gemspec) {} if edge_gemspec
60
63
 
61
- CLEAN.include('lib/concurrent/2.*', 'lib/concurrent/*.jar')
64
+ CLEAN.include('lib/concurrent-ruby/concurrent/2.*', 'lib/concurrent-ruby/concurrent/*.jar')
62
65
 
63
66
  begin
64
67
  require 'rspec'
@@ -163,8 +166,8 @@ begin
163
166
  '--output-dir', output_dir,
164
167
  '--main', 'tmp/README.md',
165
168
  *common_yard_options)
166
- yard.files = ['./lib/**/*.rb',
167
- './lib-edge/**/*.rb',
169
+ yard.files = ['./lib/concurrent-ruby/**/*.rb',
170
+ './lib/concurrent-ruby-edge/**/*.rb',
168
171
  './ext/concurrent_ruby_ext/**/*.c',
169
172
  '-',
170
173
  'docs-source/thread_pools.md',
@@ -173,7 +176,9 @@ begin
173
176
  'LICENSE.md',
174
177
  'CHANGELOG.md']
175
178
  end
176
- Rake::Task[name].prerequisites.push removal_name, 'yard:eval_md', 'yard:update_readme'
179
+ Rake::Task[name].prerequisites.push removal_name,
180
+ # 'yard:eval_md',
181
+ 'yard:update_readme'
177
182
  end
178
183
 
179
184
  define_yard_task.call current_yard_version_name
@@ -227,8 +232,8 @@ task :release => ['release:checks', 'release:build', 'release:test', 'release:pu
227
232
  namespace :release do
228
233
  # Depends on environment of @pitr-ch
229
234
 
230
- mri_version = '2.5.1'
231
- jruby_version = 'jruby-9.1.17.1'
235
+ mri_version = '2.6.5'
236
+ jruby_version = 'jruby-9.2.9.0'
232
237
 
233
238
  task :checks => "yard:#{current_yard_version_name}:uptodate" do
234
239
  Dir.chdir(__dir__) do
@@ -10,11 +10,11 @@ module Concurrent
10
10
  # or writing at a time. This includes iteration methods like `#each`.
11
11
  #
12
12
  # @note `a += b` is **not** a **thread-safe** operation on
13
- # `Concurrent::Array`. It reads array `a`, then it creates new `Concurrent::Array`
14
- # which is concatenation of `a` and `b`, then it writes the concatenation to `a`.
15
- # The read and write are independent operations they do not form a single atomic
16
- # operation therefore when two `+=` operations are executed concurrently updates
17
- # may be lost. Use `#concat` instead.
13
+ # `Concurrent::Array`. It reads array `a`, then it creates new `Concurrent::Array`
14
+ # which is concatenation of `a` and `b`, then it writes the concatenation to `a`.
15
+ # The read and write are independent operations they do not form a single atomic
16
+ # operation therefore when two `+=` operations are executed concurrently updates
17
+ # may be lost. Use `#concat` instead.
18
18
  #
19
19
  # @see http://ruby-doc.org/core-2.2.0/Array.html Ruby standard library `Array`
20
20
 
@@ -18,7 +18,7 @@ require 'concurrent/synchronization'
18
18
  # uncoordinated, *synchronous* change of individual values. Best used when
19
19
  # the value will undergo frequent reads but only occasional, though complex,
20
20
  # updates. Suitable when the result of an update must be known immediately.
21
- # * *{Concurrent::AtomicReference}:* A simple object reference that can be
21
+ # * *{Concurrent::AtomicReference}:* A simple object reference that can be updated
22
22
  # atomically. Updates are synchronous but fast. Best used when updates a
23
23
  # simple set operations. Not suitable when updates are complex.
24
24
  # {Concurrent::AtomicBoolean} and {Concurrent::AtomicFixnum} are similar
@@ -41,13 +41,13 @@ module Concurrent
41
41
  #
42
42
  # Explicitly sets the value to true.
43
43
  #
44
- # @return [Boolean] true is value has changed, otherwise false
44
+ # @return [Boolean] true if value has changed, otherwise false
45
45
 
46
46
  # @!macro atomic_boolean_method_make_false
47
47
  #
48
48
  # Explicitly sets the value to false.
49
49
  #
50
- # @return [Boolean] true is value has changed, otherwise false
50
+ # @return [Boolean] true if value has changed, otherwise false
51
51
 
52
52
  ###################################################################
53
53
 
@@ -1,6 +1,6 @@
1
+ require 'concurrent/utility/engine'
1
2
  require 'concurrent/atomic/mutex_count_down_latch'
2
3
  require 'concurrent/atomic/java_count_down_latch'
3
- require 'concurrent/utility/engine'
4
4
 
5
5
  module Concurrent
6
6
 
@@ -32,12 +32,38 @@ module Concurrent
32
32
  FREE = []
33
33
  LOCK = Mutex.new
34
34
  ARRAYS = {} # used as a hash set
35
+ # noinspection RubyClassVariableUsageInspection
35
36
  @@next = 0
36
- private_constant :FREE, :LOCK, :ARRAYS
37
+ QUEUE = Queue.new
38
+ THREAD = Thread.new do
39
+ while true
40
+ method, i = QUEUE.pop
41
+ case method
42
+ when :thread_local_finalizer
43
+ LOCK.synchronize do
44
+ FREE.push(i)
45
+ # The cost of GC'ing a TLV is linear in the number of threads using TLVs
46
+ # But that is natural! More threads means more storage is used per TLV
47
+ # So naturally more CPU time is required to free more storage
48
+ ARRAYS.each_value do |array|
49
+ array[i] = nil
50
+ end
51
+ end
52
+ when :thread_finalizer
53
+ LOCK.synchronize do
54
+ # The thread which used this thread-local array is now gone
55
+ # So don't hold onto a reference to the array (thus blocking GC)
56
+ ARRAYS.delete(i)
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ private_constant :FREE, :LOCK, :ARRAYS, :QUEUE, :THREAD
37
63
 
38
64
  # @!macro thread_local_var_method_get
39
65
  def value
40
- if array = get_threadlocal_array
66
+ if (array = get_threadlocal_array)
41
67
  value = array[@index]
42
68
  if value.nil?
43
69
  default
@@ -57,10 +83,10 @@ module Concurrent
57
83
  # We could keep the thread-local arrays in a hash, keyed by Thread
58
84
  # But why? That would require locking
59
85
  # Using Ruby's built-in thread-local storage is faster
60
- unless array = get_threadlocal_array(me)
86
+ unless (array = get_threadlocal_array(me))
61
87
  array = set_threadlocal_array([], me)
62
88
  LOCK.synchronize { ARRAYS[array.object_id] = array }
63
- ObjectSpace.define_finalizer(me, self.class.thread_finalizer(array))
89
+ ObjectSpace.define_finalizer(me, self.class.thread_finalizer(array.object_id))
64
90
  end
65
91
  array[@index] = (value.nil? ? NULL : value)
66
92
  value
@@ -69,6 +95,7 @@ module Concurrent
69
95
  protected
70
96
 
71
97
  # @!visibility private
98
+ # noinspection RubyClassVariableUsageInspection
72
99
  def allocate_storage
73
100
  @index = LOCK.synchronize do
74
101
  FREE.pop || begin
@@ -77,37 +104,19 @@ module Concurrent
77
104
  result
78
105
  end
79
106
  end
80
- ObjectSpace.define_finalizer(self, self.class.threadlocal_finalizer(@index))
107
+ ObjectSpace.define_finalizer(self, self.class.thread_local_finalizer(@index))
81
108
  end
82
109
 
83
110
  # @!visibility private
84
- def self.threadlocal_finalizer(index)
85
- proc do
86
- Thread.new do # avoid error: can't be called from trap context
87
- LOCK.synchronize do
88
- FREE.push(index)
89
- # The cost of GC'ing a TLV is linear in the number of threads using TLVs
90
- # But that is natural! More threads means more storage is used per TLV
91
- # So naturally more CPU time is required to free more storage
92
- ARRAYS.each_value do |array|
93
- array[index] = nil
94
- end
95
- end
96
- end
97
- end
111
+ def self.thread_local_finalizer(index)
112
+ # avoid error: can't be called from trap context
113
+ proc { QUEUE.push [:thread_local_finalizer, index] }
98
114
  end
99
115
 
100
116
  # @!visibility private
101
- def self.thread_finalizer(array)
102
- proc do
103
- Thread.new do # avoid error: can't be called from trap context
104
- LOCK.synchronize do
105
- # The thread which used this thread-local array is now gone
106
- # So don't hold onto a reference to the array (thus blocking GC)
107
- ARRAYS.delete(array.object_id)
108
- end
109
- end
110
- end
117
+ def self.thread_finalizer(id)
118
+ # avoid error: can't be called from trap context
119
+ proc { QUEUE.push [:thread_finalizer, id] }
111
120
  end
112
121
 
113
122
  private
@@ -136,21 +145,22 @@ module Concurrent
136
145
  # This exists only for use in testing
137
146
  # @!visibility private
138
147
  def value_for(thread)
139
- if array = get_threadlocal_array(thread)
148
+ if (array = get_threadlocal_array(thread))
140
149
  value = array[@index]
141
150
  if value.nil?
142
- default_for(thread)
151
+ get_default
143
152
  elsif value.equal?(NULL)
144
153
  nil
145
154
  else
146
155
  value
147
156
  end
148
157
  else
149
- default_for(thread)
158
+ get_default
150
159
  end
151
160
  end
152
161
 
153
- def default_for(thread)
162
+ # @!visibility private
163
+ def get_default
154
164
  if @default_block
155
165
  raise "Cannot use default_for with default block"
156
166
  else
@@ -1,6 +1,6 @@
1
+ require 'concurrent/utility/engine'
1
2
  require 'concurrent/atomic/ruby_thread_local_var'
2
3
  require 'concurrent/atomic/java_thread_local_var'
3
- require 'concurrent/utility/engine'
4
4
 
5
5
  module Concurrent
6
6
 
@@ -1,6 +1,6 @@
1
+ require 'concurrent/utility/engine'
1
2
  require 'concurrent/collection/java_non_concurrent_priority_queue'
2
3
  require 'concurrent/collection/ruby_non_concurrent_priority_queue'
3
- require 'concurrent/utility/engine'
4
4
 
5
5
  module Concurrent
6
6
  module Collection
@@ -37,8 +37,8 @@ module Concurrent
37
37
  # returning data to the caller (dereferencing).
38
38
  #
39
39
  # @note Most classes that include this module will call `#set_deref_options`
40
- # from within the constructor, thus allowing these options to be set at
41
- # object creation.
40
+ # from within the constructor, thus allowing these options to be set at
41
+ # object creation.
42
42
  #
43
43
  # @param [Hash] opts the options defining dereference behavior.
44
44
  # @option opts [String] :dup_on_deref (false) call `#dup` before returning the data
@@ -3,13 +3,14 @@ require 'concurrent/delay'
3
3
  require 'concurrent/errors'
4
4
  require 'concurrent/atomic/atomic_reference'
5
5
  require 'concurrent/concern/logging'
6
+ require 'concurrent/concern/deprecation'
6
7
  require 'concurrent/executor/immediate_executor'
7
8
  require 'concurrent/executor/cached_thread_pool'
8
- require 'concurrent/utility/at_exit'
9
9
  require 'concurrent/utility/processor_counter'
10
10
 
11
11
  module Concurrent
12
12
  extend Concern::Logging
13
+ extend Concern::Deprecation
13
14
 
14
15
  autoload :Options, 'concurrent/options'
15
16
  autoload :TimerSet, 'concurrent/executor/timer_set'
@@ -97,15 +98,15 @@ module Concurrent
97
98
  end
98
99
 
99
100
  # @!visibility private
100
- GLOBAL_FAST_EXECUTOR = Delay.new { Concurrent.new_fast_executor(auto_terminate: true) }
101
+ GLOBAL_FAST_EXECUTOR = Delay.new { Concurrent.new_fast_executor }
101
102
  private_constant :GLOBAL_FAST_EXECUTOR
102
103
 
103
104
  # @!visibility private
104
- GLOBAL_IO_EXECUTOR = Delay.new { Concurrent.new_io_executor(auto_terminate: true) }
105
+ GLOBAL_IO_EXECUTOR = Delay.new { Concurrent.new_io_executor }
105
106
  private_constant :GLOBAL_IO_EXECUTOR
106
107
 
107
108
  # @!visibility private
108
- GLOBAL_TIMER_SET = Delay.new { TimerSet.new(auto_terminate: true) }
109
+ GLOBAL_TIMER_SET = Delay.new { TimerSet.new }
109
110
  private_constant :GLOBAL_TIMER_SET
110
111
 
111
112
  # @!visibility private
@@ -115,7 +116,7 @@ module Concurrent
115
116
  # Disables AtExit handlers including pool auto-termination handlers.
116
117
  # When disabled it will be the application programmer's responsibility
117
118
  # to ensure that the handlers are shutdown properly prior to application
118
- # exit by calling {AtExit.run} method.
119
+ # exit by calling `AtExit.run` method.
119
120
  #
120
121
  # @note this option should be needed only because of `at_exit` ordering
121
122
  # issues which may arise when running some of the testing frameworks.
@@ -125,9 +126,10 @@ module Concurrent
125
126
  # @note This method should *never* be called
126
127
  # from within a gem. It should *only* be used from within the main
127
128
  # application and even then it should be used only when necessary.
128
- # @see AtExit
129
+ # @deprecated Has no effect since it is no longer needed, see https://github.com/ruby-concurrency/concurrent-ruby/pull/841.
130
+ #
129
131
  def self.disable_at_exit_handlers!
130
- AtExit.enabled = false
132
+ deprecated "Method #disable_at_exit_handlers! has no effect since it is no longer needed, see https://github.com/ruby-concurrency/concurrent-ruby/pull/841."
131
133
  end
132
134
 
133
135
  # Global thread pool optimized for short, fast *operations*.
@@ -171,14 +173,16 @@ module Concurrent
171
173
  auto_terminate: opts.fetch(:auto_terminate, true),
172
174
  idletime: 60, # 1 minute
173
175
  max_queue: 0, # unlimited
174
- fallback_policy: :abort # shouldn't matter -- 0 max queue
176
+ fallback_policy: :abort, # shouldn't matter -- 0 max queue
177
+ name: "fast"
175
178
  )
176
179
  end
177
180
 
178
181
  def self.new_io_executor(opts = {})
179
182
  CachedThreadPool.new(
180
183
  auto_terminate: opts.fetch(:auto_terminate, true),
181
- fallback_policy: :abort # shouldn't matter -- 0 max queue
184
+ fallback_policy: :abort, # shouldn't matter -- 0 max queue
185
+ name: "io"
182
186
  )
183
187
  end
184
188
  end
@@ -1,7 +1,7 @@
1
1
  require 'concurrent/errors'
2
+ require 'concurrent/concern/deprecation'
2
3
  require 'concurrent/executor/executor_service'
3
4
  require 'concurrent/synchronization'
4
- require 'concurrent/utility/at_exit'
5
5
 
6
6
  module Concurrent
7
7
 
@@ -9,6 +9,7 @@ module Concurrent
9
9
  # @!visibility private
10
10
  class AbstractExecutorService < Synchronization::LockableObject
11
11
  include ExecutorService
12
+ include Concern::Deprecation
12
13
 
13
14
  # The set of possible fallback policies that may be set at thread pool creation.
14
15
  FALLBACK_POLICIES = [:abort, :discard, :caller_runs].freeze
@@ -16,10 +17,20 @@ module Concurrent
16
17
  # @!macro executor_service_attr_reader_fallback_policy
17
18
  attr_reader :fallback_policy
18
19
 
20
+ attr_reader :name
21
+
19
22
  # Create a new thread pool.
20
- def initialize(*args, &block)
23
+ def initialize(opts = {}, &block)
21
24
  super(&nil)
22
- synchronize { ns_initialize(*args, &block) }
25
+ synchronize do
26
+ @auto_terminate = opts.fetch(:auto_terminate, true)
27
+ @name = opts.fetch(:name) if opts.key?(:name)
28
+ ns_initialize(opts, &block)
29
+ end
30
+ end
31
+
32
+ def to_s
33
+ name ? "#{super[0..-2]} name: #{name}>" : super
23
34
  end
24
35
 
25
36
  # @!macro executor_service_method_shutdown
@@ -54,12 +65,12 @@ module Concurrent
54
65
 
55
66
  # @!macro executor_service_method_auto_terminate_question
56
67
  def auto_terminate?
57
- synchronize { ns_auto_terminate? }
68
+ synchronize { @auto_terminate }
58
69
  end
59
70
 
60
71
  # @!macro executor_service_method_auto_terminate_setter
61
72
  def auto_terminate=(value)
62
- synchronize { self.ns_auto_terminate = value }
73
+ deprecated "Method #auto_terminate= has no effect. Set :auto_terminate option when executor is initialized."
63
74
  end
64
75
 
65
76
  private
@@ -110,25 +121,8 @@ module Concurrent
110
121
  end
111
122
 
112
123
  def ns_auto_terminate?
113
- !!@auto_terminate
124
+ @auto_terminate
114
125
  end
115
126
 
116
- def ns_auto_terminate=(value)
117
- case value
118
- when true
119
- AtExit.add(self) { terminate_at_exit }
120
- @auto_terminate = true
121
- when false
122
- AtExit.delete(self)
123
- @auto_terminate = false
124
- else
125
- raise ArgumentError
126
- end
127
- end
128
-
129
- def terminate_at_exit
130
- kill # TODO be gentle first
131
- wait_for_termination(10)
132
- end
133
127
  end
134
128
  end