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
@@ -37,7 +37,7 @@ module Concurrent
37
37
  #
38
38
  # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newCachedThreadPool--
39
39
  def initialize(opts = {})
40
- defaults = { idletime: DEFAULT_THREAD_IDLETIMEOUT }
40
+ defaults = { idletime: DEFAULT_THREAD_IDLETIMEOUT }
41
41
  overrides = { min_threads: 0,
42
42
  max_threads: DEFAULT_MAX_POOL_SIZE,
43
43
  max_queue: DEFAULT_MAX_QUEUE_SIZE }
@@ -51,11 +51,11 @@ module Concurrent
51
51
  def ns_initialize(opts)
52
52
  super(opts)
53
53
  if Concurrent.on_jruby?
54
- @max_queue = 0
55
- @executor = java.util.concurrent.Executors.newCachedThreadPool
54
+ @max_queue = 0
55
+ @executor = java.util.concurrent.Executors.newCachedThreadPool(
56
+ DaemonThreadFactory.new(ns_auto_terminate?))
56
57
  @executor.setRejectedExecutionHandler(FALLBACK_POLICY_CLASSES[@fallback_policy].new)
57
58
  @executor.setKeepAliveTime(opts.fetch(:idletime, DEFAULT_THREAD_IDLETIMEOUT), java.util.concurrent.TimeUnit::SECONDS)
58
- self.auto_terminate = opts.fetch(:auto_terminate, true)
59
59
  end
60
60
  end
61
61
  end
@@ -111,10 +111,10 @@ module Concurrent
111
111
 
112
112
  # @!macro executor_service_method_auto_terminate_setter
113
113
  #
114
- # Set the auto-terminate behavior for this executor.
115
114
  #
115
+ # Set the auto-terminate behavior for this executor.
116
+ # @deprecated Has no effect
116
117
  # @param [Boolean] value The new auto-terminate value to set for this executor.
117
- #
118
118
  # @return [Boolean] `true` when auto-termination is enabled else `false`.
119
119
 
120
120
  ###################################################################
@@ -115,12 +115,13 @@ module Concurrent
115
115
  # Thread pools support several configuration options:
116
116
  #
117
117
  # * `idletime`: The number of seconds that a thread may be idle before being reclaimed.
118
+ # * `name`: The name of the executor (optional). Printed in the executor's `#to_s` output and
119
+ # a `<name>-worker-<id>` name is given to its threads if supported by used Ruby
120
+ # implementation. `<id>` is uniq for each thread.
118
121
  # * `max_queue`: The maximum number of tasks that may be waiting in the work queue at
119
122
  # any one time. When the queue size reaches `max_queue` and no new threads can be created,
120
123
  # subsequent tasks will be rejected in accordance with the configured `fallback_policy`.
121
- # * `auto_terminate`: When true (default) an `at_exit` handler will be registered which
122
- # will stop the thread pool when the application exits. See below for more information
123
- # on shutting down thread pools.
124
+ # * `auto_terminate`: When true (default), the threads started will be marked as daemon.
124
125
  # * `fallback_policy`: The policy defining how rejected tasks are handled.
125
126
  #
126
127
  # Three fallback policies are supported:
@@ -145,16 +146,12 @@ module Concurrent
145
146
  #
146
147
  # On some runtime platforms (most notably the JVM) the application will not
147
148
  # exit until all thread pools have been shutdown. To prevent applications from
148
- # "hanging" on exit all thread pools include an `at_exit` handler that will
149
- # stop the thread pool when the application exits. This handler uses a brute
150
- # force method to stop the pool and makes no guarantees regarding resources being
151
- # used by any tasks still running. Registration of this `at_exit` handler can be
152
- # prevented by setting the thread pool's constructor `:auto_terminate` option to
153
- # `false` when the thread pool is created. All thread pools support this option.
149
+ # "hanging" on exit, all threads can be marked as daemon according to the
150
+ # `:auto_terminate` option.
154
151
  #
155
152
  # ```ruby
156
- # pool1 = Concurrent::FixedThreadPool.new(5) # an `at_exit` handler will be registered
157
- # pool2 = Concurrent::FixedThreadPool.new(5, auto_terminate: false) # prevent `at_exit` handler registration
153
+ # pool1 = Concurrent::FixedThreadPool.new(5) # threads will be marked as daemon
154
+ # pool2 = Concurrent::FixedThreadPool.new(5, auto_terminate: false) # mark threads as non-daemon
158
155
  # ```
159
156
  #
160
157
  # @note Failure to properly shutdown a thread pool can lead to unpredictable results.
@@ -163,7 +160,7 @@ module Concurrent
163
160
  # @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html Java Tutorials: Thread Pools
164
161
  # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html Java Executors class
165
162
  # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html Java ExecutorService interface
166
- # @see http://ruby-doc.org//core-2.2.0/Kernel.html#method-i-at_exit Kernel#at_exit
163
+ # @see https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#setDaemon-boolean-
167
164
 
168
165
 
169
166
 
@@ -18,10 +18,6 @@ if Concurrent.on_jruby?
18
18
  }.freeze
19
19
  private_constant :FALLBACK_POLICY_CLASSES
20
20
 
21
- def initialize(*args, &block)
22
- super
23
- end
24
-
25
21
  def post(*args, &task)
26
22
  raise ArgumentError.new('no block given') unless block_given?
27
23
  return handle_fallback(*args, &task) unless running?
@@ -42,7 +38,6 @@ if Concurrent.on_jruby?
42
38
 
43
39
  def shutdown
44
40
  synchronize do
45
- self.ns_auto_terminate = false
46
41
  @executor.shutdown
47
42
  nil
48
43
  end
@@ -50,7 +45,6 @@ if Concurrent.on_jruby?
50
45
 
51
46
  def kill
52
47
  synchronize do
53
- self.ns_auto_terminate = false
54
48
  @executor.shutdownNow
55
49
  nil
56
50
  end
@@ -87,5 +81,23 @@ if Concurrent.on_jruby?
87
81
  end
88
82
  private_constant :Job
89
83
  end
84
+
85
+ class DaemonThreadFactory
86
+ # hide include from YARD
87
+ send :include, java.util.concurrent.ThreadFactory
88
+
89
+ def initialize(daemonize = true)
90
+ @daemonize = daemonize
91
+ end
92
+
93
+ def newThread(runnable)
94
+ thread = java.util.concurrent.Executors.defaultThreadFactory().newThread(runnable)
95
+ thread.setDaemon(@daemonize)
96
+ return thread
97
+ end
98
+ end
99
+
100
+ private_constant :DaemonThreadFactory
101
+
90
102
  end
91
103
  end
@@ -17,12 +17,13 @@ if Concurrent.on_jruby?
17
17
  end
18
18
 
19
19
  private
20
-
20
+
21
21
  def ns_initialize(opts)
22
- @executor = java.util.concurrent.Executors.newSingleThreadExecutor
22
+ @executor = java.util.concurrent.Executors.newSingleThreadExecutor(
23
+ DaemonThreadFactory.new(ns_auto_terminate?)
24
+ )
23
25
  @fallback_policy = opts.fetch(:fallback_policy, :discard)
24
26
  raise ArgumentError.new("#{@fallback_policy} is not a valid fallback policy") unless FALLBACK_POLICY_CLASSES.keys.include?(@fallback_policy)
25
- self.auto_terminate = opts.fetch(:auto_terminate, true)
26
27
  end
27
28
  end
28
29
  end
@@ -114,10 +114,11 @@ if Concurrent.on_jruby?
114
114
  idletime,
115
115
  java.util.concurrent.TimeUnit::SECONDS,
116
116
  queue,
117
+ DaemonThreadFactory.new(ns_auto_terminate?),
117
118
  FALLBACK_POLICY_CLASSES[@fallback_policy].new)
118
119
 
119
- self.auto_terminate = opts.fetch(:auto_terminate, true)
120
120
  end
121
121
  end
122
+
122
123
  end
123
124
  end
@@ -27,7 +27,6 @@ module Concurrent
27
27
  def shutdown
28
28
  synchronize do
29
29
  break unless running?
30
- self.ns_auto_terminate = false
31
30
  stop_event.set
32
31
  ns_shutdown_execution
33
32
  end
@@ -37,7 +36,6 @@ module Concurrent
37
36
  def kill
38
37
  synchronize do
39
38
  break if shutdown?
40
- self.ns_auto_terminate = false
41
39
  stop_event.set
42
40
  ns_kill_execution
43
41
  stopped_event.set
@@ -15,7 +15,6 @@ module Concurrent
15
15
  max_queue: 0,
16
16
  idletime: DEFAULT_THREAD_IDLETIMEOUT,
17
17
  fallback_policy: opts.fetch(:fallback_policy, :discard),
18
- auto_terminate: opts.fetch(:auto_terminate, true)
19
18
  )
20
19
  end
21
20
  end
@@ -122,8 +122,6 @@ module Concurrent
122
122
  raise ArgumentError.new("`min_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if @min_length < DEFAULT_MIN_POOL_SIZE
123
123
  raise ArgumentError.new("`min_threads` cannot be more than `max_threads`") if min_length > max_length
124
124
 
125
- self.auto_terminate = opts.fetch(:auto_terminate, true)
126
-
127
125
  @pool = [] # all workers
128
126
  @ready = [] # used as a stash (most idle worker is at the start)
129
127
  @queue = [] # used as queue
@@ -131,6 +129,7 @@ module Concurrent
131
129
  @scheduled_task_count = 0
132
130
  @completed_task_count = 0
133
131
  @largest_length = 0
132
+ @workers_counter = 0
134
133
  @ruby_pid = $$ # detects if Ruby has forked
135
134
 
136
135
  @gc_interval = opts.fetch(:gc_interval, @idletime / 2.0).to_i # undocumented
@@ -224,7 +223,8 @@ module Concurrent
224
223
  def ns_add_busy_worker
225
224
  return if @pool.size >= @max_length
226
225
 
227
- @pool << (worker = Worker.new(self))
226
+ @workers_counter += 1
227
+ @pool << (worker = Worker.new(self, @workers_counter))
228
228
  @largest_length = @pool.length if @pool.length > @largest_length
229
229
  worker
230
230
  end
@@ -284,6 +284,7 @@ module Concurrent
284
284
  @scheduled_task_count = 0
285
285
  @completed_task_count = 0
286
286
  @largest_length = 0
287
+ @workers_counter = 0
287
288
  @ruby_pid = $$
288
289
  end
289
290
  end
@@ -292,11 +293,15 @@ module Concurrent
292
293
  class Worker
293
294
  include Concern::Logging
294
295
 
295
- def initialize(pool)
296
+ def initialize(pool, id)
296
297
  # instance variables accessed only under pool's lock so no need to sync here again
297
298
  @queue = Queue.new
298
299
  @pool = pool
299
300
  @thread = create_worker @queue, pool, pool.idletime
301
+
302
+ if @thread.respond_to?(:name=)
303
+ @thread.name = [pool.name, 'worker', id].compact.join('-')
304
+ end
300
305
  end
301
306
 
302
307
  def <<(message)
@@ -91,7 +91,7 @@ module Concurrent
91
91
 
92
92
  private
93
93
 
94
- def ns_initialize
94
+ def ns_initialize(*args)
95
95
  @running = Concurrent::AtomicBoolean.new(true)
96
96
  @stopped = Concurrent::Event.new
97
97
  @count = Concurrent::AtomicFixnum.new(0)
@@ -1,3 +1,4 @@
1
+ require 'concurrent/utility/engine'
1
2
  require 'concurrent/executor/ruby_single_thread_executor'
2
3
 
3
4
  module Concurrent
@@ -77,7 +77,6 @@ module Concurrent
77
77
  @timer_executor = SingleThreadExecutor.new
78
78
  @condition = Event.new
79
79
  @ruby_pid = $$ # detects if Ruby has forked
80
- self.auto_terminate = opts.fetch(:auto_terminate, true)
81
80
  end
82
81
 
83
82
  # Post the task to the internal queue.
@@ -70,6 +70,14 @@ module Concurrent
70
70
  ns_select(&block)
71
71
  end
72
72
 
73
+ private
74
+
75
+ # @!visibility private
76
+ def initialize_copy(original)
77
+ super(original)
78
+ ns_initialize_copy
79
+ end
80
+
73
81
  # @!macro struct_new
74
82
  def self.new(*args, &block)
75
83
  clazz_name = nil
@@ -197,7 +197,7 @@ module Concurrent
197
197
  # Insert value into map with key if key is absent in one atomic step.
198
198
  # @param [Object] key
199
199
  # @param [Object] value
200
- # @return [Object, nil] the value or nil when key was present
200
+ # @return [Object, nil] the previous value when key was present or nil when there was no key
201
201
  def put_if_absent(key, value)
202
202
  computed = false
203
203
  result = compute_if_absent(key) do
@@ -196,6 +196,16 @@ module Concurrent
196
196
  raise NameError.new("no member '#{member}' in struct")
197
197
  end
198
198
 
199
+ private
200
+
201
+ # @!visibility private
202
+ def initialize_copy(original)
203
+ synchronize do
204
+ super(original)
205
+ ns_initialize_copy
206
+ end
207
+ end
208
+
199
209
  # @!macro struct_new
200
210
  def self.new(*args, &block)
201
211
  clazz_name = nil
@@ -11,11 +11,11 @@ module Concurrent
11
11
  # or writing at a time. This includes iteration methods like `#each`.
12
12
  #
13
13
  # @note `a += b` is **not** a **thread-safe** operation on
14
- # `Concurrent::Set`. It reads Set `a`, then it creates new `Concurrent::Set`
15
- # which is union of `a` and `b`, then it writes the union to `a`.
16
- # The read and write are independent operations they do not form a single atomic
17
- # operation therefore when two `+=` operations are executed concurrently updates
18
- # may be lost. Use `#merge` instead.
14
+ # `Concurrent::Set`. It reads Set `a`, then it creates new `Concurrent::Set`
15
+ # which is union of `a` and `b`, then it writes the union to `a`.
16
+ # The read and write are independent operations they do not form a single atomic
17
+ # operation therefore when two `+=` operations are executed concurrently updates
18
+ # may be lost. Use `#merge` instead.
19
19
  #
20
20
  # @see http://ruby-doc.org/stdlib-2.4.0/libdoc/set/rdoc/Set.html Ruby standard library `Set`
21
21
 
@@ -91,6 +91,16 @@ module Concurrent
91
91
  raise NameError.new("no member '#{member}' in struct")
92
92
  end
93
93
 
94
+ private
95
+
96
+ # @!visibility private
97
+ def initialize_copy(original)
98
+ synchronize do
99
+ super(original)
100
+ ns_initialize_copy
101
+ end
102
+ end
103
+
94
104
  # @!macro struct_new
95
105
  def self.new(*args, &block)
96
106
  clazz_name = nil
@@ -115,6 +115,17 @@ module Concurrent
115
115
  self.class.new(*self.to_h.merge(other, &block).values)
116
116
  end
117
117
 
118
+ # @!visibility private
119
+ def ns_initialize_copy
120
+ @values = @values.map do |val|
121
+ begin
122
+ val.clone
123
+ rescue TypeError
124
+ val
125
+ end
126
+ end
127
+ end
128
+
118
129
  # @!visibility private
119
130
  def pr_underscore(clazz)
120
131
  word = clazz.to_s.dup # dup string to workaround JRuby 9.2.0.0 bug https://github.com/jruby/jruby/issues/5229
@@ -1,3 +1,4 @@
1
+ require 'etc'
1
2
  require 'rbconfig'
2
3
  require 'concurrent/delay'
3
4
 
@@ -22,6 +23,8 @@ module Concurrent
22
23
  # occasionally poll this property." Subsequently the result will NOT be
23
24
  # memoized under JRuby.
24
25
  #
26
+ # Ruby's Etc.nprocessors will be used if available (MRI 2.2+).
27
+ #
25
28
  # On Windows the Win32 API will be queried for the
26
29
  # `NumberOfLogicalProcessors from Win32_Processor`. This will return the
27
30
  # total number "logical processors for the current instance of the
@@ -76,6 +79,8 @@ module Concurrent
76
79
  def compute_processor_count
77
80
  if Concurrent.on_jruby?
78
81
  java.lang.Runtime.getRuntime.availableProcessors
82
+ elsif Etc.respond_to?(:nprocessors) && (nprocessor = Etc.nprocessors rescue nil)
83
+ nprocessor
79
84
  else
80
85
  os_name = RbConfig::CONFIG["target_os"]
81
86
  if os_name =~ /mingw|mswin/
@@ -0,0 +1,3 @@
1
+ module Concurrent
2
+ VERSION = '1.1.6'
3
+ end