concurrent-ruby 1.1.5 → 1.1.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +51 -1
  3. data/Gemfile +5 -4
  4. data/{LICENSE.md → LICENSE.txt} +18 -20
  5. data/README.md +34 -7
  6. data/Rakefile +44 -32
  7. data/lib/{concurrent-ruby.rb → concurrent-ruby/concurrent-ruby.rb} +0 -0
  8. data/lib/{concurrent.rb → concurrent-ruby/concurrent.rb} +0 -0
  9. data/lib/{concurrent → concurrent-ruby/concurrent}/agent.rb +0 -0
  10. data/lib/{concurrent → concurrent-ruby/concurrent}/array.rb +6 -6
  11. data/lib/{concurrent → concurrent-ruby/concurrent}/async.rb +9 -20
  12. data/lib/{concurrent → concurrent-ruby/concurrent}/atom.rb +1 -1
  13. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/abstract_thread_local_var.rb +0 -0
  14. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_boolean.rb +2 -2
  15. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_fixnum.rb +0 -0
  16. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_markable_reference.rb +0 -0
  17. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_reference.rb +0 -0
  18. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/count_down_latch.rb +1 -1
  19. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/cyclic_barrier.rb +0 -0
  20. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/event.rb +0 -0
  21. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/java_count_down_latch.rb +0 -0
  22. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/java_thread_local_var.rb +0 -0
  23. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_atomic_boolean.rb +0 -0
  24. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_atomic_fixnum.rb +0 -0
  25. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_count_down_latch.rb +0 -0
  26. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_semaphore.rb +0 -0
  27. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/read_write_lock.rb +0 -0
  28. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/reentrant_read_write_lock.rb +0 -0
  29. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/ruby_thread_local_var.rb +60 -40
  30. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/semaphore.rb +0 -0
  31. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/thread_local_var.rb +1 -1
  32. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic_reference/mutex_atomic.rb +0 -0
  33. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic_reference/numeric_cas_wrapper.rb +0 -0
  34. data/lib/{concurrent → concurrent-ruby/concurrent}/atomics.rb +0 -0
  35. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/copy_on_notify_observer_set.rb +0 -0
  36. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/copy_on_write_observer_set.rb +0 -0
  37. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/java_non_concurrent_priority_queue.rb +0 -0
  38. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/lock_free_stack.rb +0 -0
  39. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/atomic_reference_map_backend.rb +0 -0
  40. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/mri_map_backend.rb +1 -1
  41. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/non_concurrent_map_backend.rb +0 -0
  42. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/synchronized_map_backend.rb +0 -0
  43. data/lib/concurrent-ruby/concurrent/collection/map/truffleruby_map_backend.rb +14 -0
  44. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/non_concurrent_priority_queue.rb +1 -1
  45. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/ruby_non_concurrent_priority_queue.rb +11 -1
  46. data/lib/{concurrent → concurrent-ruby/concurrent}/concern/deprecation.rb +0 -0
  47. data/lib/{concurrent → concurrent-ruby/concurrent}/concern/dereferenceable.rb +2 -2
  48. data/lib/{concurrent → concurrent-ruby/concurrent}/concern/logging.rb +0 -0
  49. data/lib/{concurrent → concurrent-ruby/concurrent}/concern/obligation.rb +0 -0
  50. data/lib/{concurrent → concurrent-ruby/concurrent}/concern/observable.rb +0 -0
  51. data/lib/concurrent-ruby/concurrent/concurrent_ruby.jar +0 -0
  52. data/lib/{concurrent → concurrent-ruby/concurrent}/configuration.rb +13 -9
  53. data/lib/{concurrent → concurrent-ruby/concurrent}/constants.rb +0 -0
  54. data/lib/{concurrent → concurrent-ruby/concurrent}/dataflow.rb +0 -0
  55. data/lib/{concurrent → concurrent-ruby/concurrent}/delay.rb +0 -0
  56. data/lib/{concurrent → concurrent-ruby/concurrent}/errors.rb +0 -0
  57. data/lib/{concurrent → concurrent-ruby/concurrent}/exchanger.rb +0 -0
  58. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/abstract_executor_service.rb +17 -23
  59. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/cached_thread_pool.rb +4 -4
  60. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/executor_service.rb +2 -2
  61. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/fixed_thread_pool.rb +16 -12
  62. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/immediate_executor.rb +0 -0
  63. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/indirect_immediate_executor.rb +0 -0
  64. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/java_executor_service.rb +18 -6
  65. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/java_single_thread_executor.rb +4 -3
  66. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/java_thread_pool_executor.rb +15 -2
  67. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/ruby_executor_service.rb +0 -2
  68. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/ruby_single_thread_executor.rb +0 -1
  69. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/ruby_thread_pool_executor.rb +20 -5
  70. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/safe_task_executor.rb +0 -0
  71. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/serial_executor_service.rb +0 -0
  72. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/serialized_execution.rb +0 -0
  73. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/serialized_execution_delegator.rb +0 -0
  74. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/simple_executor_service.rb +1 -1
  75. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/single_thread_executor.rb +1 -0
  76. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/thread_pool_executor.rb +2 -1
  77. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/timer_set.rb +0 -1
  78. data/lib/{concurrent → concurrent-ruby/concurrent}/executors.rb +0 -0
  79. data/lib/{concurrent → concurrent-ruby/concurrent}/future.rb +0 -0
  80. data/lib/{concurrent → concurrent-ruby/concurrent}/hash.rb +1 -1
  81. data/lib/{concurrent → concurrent-ruby/concurrent}/immutable_struct.rb +9 -1
  82. data/lib/{concurrent → concurrent-ruby/concurrent}/ivar.rb +0 -0
  83. data/lib/{concurrent → concurrent-ruby/concurrent}/map.rb +14 -4
  84. data/lib/{concurrent → concurrent-ruby/concurrent}/maybe.rb +0 -0
  85. data/lib/{concurrent → concurrent-ruby/concurrent}/mutable_struct.rb +12 -2
  86. data/lib/{concurrent → concurrent-ruby/concurrent}/mvar.rb +0 -0
  87. data/lib/{concurrent → concurrent-ruby/concurrent}/options.rb +0 -0
  88. data/lib/{concurrent → concurrent-ruby/concurrent}/promise.rb +1 -0
  89. data/lib/{concurrent → concurrent-ruby/concurrent}/promises.rb +0 -0
  90. data/lib/{concurrent → concurrent-ruby/concurrent}/re_include.rb +0 -0
  91. data/lib/{concurrent → concurrent-ruby/concurrent}/scheduled_task.rb +0 -0
  92. data/lib/{concurrent → concurrent-ruby/concurrent}/set.rb +19 -11
  93. data/lib/{concurrent → concurrent-ruby/concurrent}/settable_struct.rb +11 -1
  94. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization.rb +0 -0
  95. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/abstract_lockable_object.rb +0 -0
  96. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/abstract_object.rb +0 -0
  97. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/abstract_struct.rb +11 -0
  98. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/condition.rb +0 -0
  99. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/jruby_lockable_object.rb +0 -0
  100. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/jruby_object.rb +0 -0
  101. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/lock.rb +0 -0
  102. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/lockable_object.rb +2 -2
  103. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/mri_object.rb +0 -0
  104. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/mutex_lockable_object.rb +12 -0
  105. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/object.rb +0 -0
  106. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/rbx_lockable_object.rb +6 -0
  107. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/rbx_object.rb +0 -0
  108. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/truffleruby_object.rb +0 -0
  109. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/volatile.rb +0 -0
  110. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/synchronized_delegator.rb +0 -0
  111. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util.rb +0 -0
  112. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/adder.rb +0 -0
  113. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/cheap_lockable.rb +0 -0
  114. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/data_structures.rb +26 -1
  115. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/power_of_two_tuple.rb +0 -0
  116. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/striped64.rb +1 -1
  117. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/volatile.rb +0 -0
  118. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/xor_shift_random.rb +0 -0
  119. data/lib/{concurrent → concurrent-ruby/concurrent}/timer_task.rb +0 -1
  120. data/lib/{concurrent → concurrent-ruby/concurrent}/tuple.rb +0 -0
  121. data/lib/{concurrent → concurrent-ruby/concurrent}/tvar.rb +9 -6
  122. data/lib/{concurrent → concurrent-ruby/concurrent}/utility/engine.rb +0 -0
  123. data/lib/{concurrent → concurrent-ruby/concurrent}/utility/monotonic_time.rb +0 -0
  124. data/lib/{concurrent → concurrent-ruby/concurrent}/utility/native_extension_loader.rb +0 -0
  125. data/lib/{concurrent → concurrent-ruby/concurrent}/utility/native_integer.rb +0 -0
  126. data/lib/{concurrent → concurrent-ruby/concurrent}/utility/processor_counter.rb +5 -0
  127. data/lib/concurrent-ruby/concurrent/version.rb +3 -0
  128. metadata +128 -128
  129. data/lib/concurrent/concurrent_ruby.jar +0 -0
  130. data/lib/concurrent/utility/at_exit.rb +0 -97
  131. data/lib/concurrent/version.rb +0 -3
@@ -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
@@ -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
  ###################################################################
@@ -16,6 +16,9 @@ module Concurrent
16
16
  # Default maximum number of seconds a thread in the pool may remain idle
17
17
  # before being reclaimed.
18
18
 
19
+ # @!macro thread_pool_executor_constant_default_synchronous
20
+ # Default value of the :synchronous option.
21
+
19
22
  # @!macro thread_pool_executor_attr_reader_max_length
20
23
  # The maximum number of threads that may be created in the pool.
21
24
  # @return [Integer] The maximum number of threads that may be created in the pool.
@@ -40,6 +43,10 @@ module Concurrent
40
43
  # The number of seconds that a thread may be idle before being reclaimed.
41
44
  # @return [Integer] The number of seconds that a thread may be idle before being reclaimed.
42
45
 
46
+ # @!macro thread_pool_executor_attr_reader_synchronous
47
+ # Whether or not a value of 0 for :max_queue option means the queue must perform direct hand-off or rather unbounded queue.
48
+ # @return [true, false]
49
+
43
50
  # @!macro thread_pool_executor_attr_reader_max_queue
44
51
  # The maximum number of tasks that may be waiting in the work queue at any one time.
45
52
  # When the queue size reaches `max_queue` subsequent tasks will be rejected in
@@ -115,12 +122,13 @@ module Concurrent
115
122
  # Thread pools support several configuration options:
116
123
  #
117
124
  # * `idletime`: The number of seconds that a thread may be idle before being reclaimed.
125
+ # * `name`: The name of the executor (optional). Printed in the executor's `#to_s` output and
126
+ # a `<name>-worker-<id>` name is given to its threads if supported by used Ruby
127
+ # implementation. `<id>` is uniq for each thread.
118
128
  # * `max_queue`: The maximum number of tasks that may be waiting in the work queue at
119
129
  # any one time. When the queue size reaches `max_queue` and no new threads can be created,
120
130
  # 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.
131
+ # * `auto_terminate`: When true (default), the threads started will be marked as daemon.
124
132
  # * `fallback_policy`: The policy defining how rejected tasks are handled.
125
133
  #
126
134
  # Three fallback policies are supported:
@@ -145,16 +153,12 @@ module Concurrent
145
153
  #
146
154
  # On some runtime platforms (most notably the JVM) the application will not
147
155
  # 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.
156
+ # "hanging" on exit, all threads can be marked as daemon according to the
157
+ # `:auto_terminate` option.
154
158
  #
155
159
  # ```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
160
+ # pool1 = Concurrent::FixedThreadPool.new(5) # threads will be marked as daemon
161
+ # pool2 = Concurrent::FixedThreadPool.new(5, auto_terminate: false) # mark threads as non-daemon
158
162
  # ```
159
163
  #
160
164
  # @note Failure to properly shutdown a thread pool can lead to unpredictable results.
@@ -163,7 +167,7 @@ module Concurrent
163
167
  # @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html Java Tutorials: Thread Pools
164
168
  # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html Java Executors class
165
169
  # @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
170
+ # @see https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#setDaemon-boolean-
167
171
 
168
172
 
169
173
 
@@ -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
@@ -21,12 +21,18 @@ if Concurrent.on_jruby?
21
21
  # @!macro thread_pool_executor_constant_default_thread_timeout
22
22
  DEFAULT_THREAD_IDLETIMEOUT = 60
23
23
 
24
+ # @!macro thread_pool_executor_constant_default_synchronous
25
+ DEFAULT_SYNCHRONOUS = false
26
+
24
27
  # @!macro thread_pool_executor_attr_reader_max_length
25
28
  attr_reader :max_length
26
29
 
27
30
  # @!macro thread_pool_executor_attr_reader_max_queue
28
31
  attr_reader :max_queue
29
32
 
33
+ # @!macro thread_pool_executor_attr_reader_synchronous
34
+ attr_reader :synchronous
35
+
30
36
  # @!macro thread_pool_executor_method_initialize
31
37
  def initialize(opts = {})
32
38
  super(opts)
@@ -94,8 +100,10 @@ if Concurrent.on_jruby?
94
100
  max_length = opts.fetch(:max_threads, DEFAULT_MAX_POOL_SIZE).to_i
95
101
  idletime = opts.fetch(:idletime, DEFAULT_THREAD_IDLETIMEOUT).to_i
96
102
  @max_queue = opts.fetch(:max_queue, DEFAULT_MAX_QUEUE_SIZE).to_i
103
+ @synchronous = opts.fetch(:synchronous, DEFAULT_SYNCHRONOUS)
97
104
  @fallback_policy = opts.fetch(:fallback_policy, :abort)
98
105
 
106
+ raise ArgumentError.new("`synchronous` cannot be set unless `max_queue` is 0") if @synchronous && @max_queue > 0
99
107
  raise ArgumentError.new("`max_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if max_length < DEFAULT_MIN_POOL_SIZE
100
108
  raise ArgumentError.new("`max_threads` cannot be greater than #{DEFAULT_MAX_POOL_SIZE}") if max_length > DEFAULT_MAX_POOL_SIZE
101
109
  raise ArgumentError.new("`min_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if min_length < DEFAULT_MIN_POOL_SIZE
@@ -103,7 +111,11 @@ if Concurrent.on_jruby?
103
111
  raise ArgumentError.new("#{fallback_policy} is not a valid fallback policy") unless FALLBACK_POLICY_CLASSES.include?(@fallback_policy)
104
112
 
105
113
  if @max_queue == 0
106
- queue = java.util.concurrent.LinkedBlockingQueue.new
114
+ if @synchronous
115
+ queue = java.util.concurrent.SynchronousQueue.new
116
+ else
117
+ queue = java.util.concurrent.LinkedBlockingQueue.new
118
+ end
107
119
  else
108
120
  queue = java.util.concurrent.LinkedBlockingQueue.new(@max_queue)
109
121
  end
@@ -114,10 +126,11 @@ if Concurrent.on_jruby?
114
126
  idletime,
115
127
  java.util.concurrent.TimeUnit::SECONDS,
116
128
  queue,
129
+ DaemonThreadFactory.new(ns_auto_terminate?),
117
130
  FALLBACK_POLICY_CLASSES[@fallback_policy].new)
118
131
 
119
- self.auto_terminate = opts.fetch(:auto_terminate, true)
120
132
  end
121
133
  end
134
+
122
135
  end
123
136
  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
@@ -23,6 +23,9 @@ module Concurrent
23
23
  # @!macro thread_pool_executor_constant_default_thread_timeout
24
24
  DEFAULT_THREAD_IDLETIMEOUT = 60
25
25
 
26
+ # @!macro thread_pool_executor_constant_default_synchronous
27
+ DEFAULT_SYNCHRONOUS = false
28
+
26
29
  # @!macro thread_pool_executor_attr_reader_max_length
27
30
  attr_reader :max_length
28
31
 
@@ -35,6 +38,9 @@ module Concurrent
35
38
  # @!macro thread_pool_executor_attr_reader_max_queue
36
39
  attr_reader :max_queue
37
40
 
41
+ # @!macro thread_pool_executor_attr_reader_synchronous
42
+ attr_reader :synchronous
43
+
38
44
  # @!macro thread_pool_executor_method_initialize
39
45
  def initialize(opts = {})
40
46
  super(opts)
@@ -114,16 +120,16 @@ module Concurrent
114
120
  @max_length = opts.fetch(:max_threads, DEFAULT_MAX_POOL_SIZE).to_i
115
121
  @idletime = opts.fetch(:idletime, DEFAULT_THREAD_IDLETIMEOUT).to_i
116
122
  @max_queue = opts.fetch(:max_queue, DEFAULT_MAX_QUEUE_SIZE).to_i
123
+ @synchronous = opts.fetch(:synchronous, DEFAULT_SYNCHRONOUS)
117
124
  @fallback_policy = opts.fetch(:fallback_policy, :abort)
118
- raise ArgumentError.new("#{@fallback_policy} is not a valid fallback policy") unless FALLBACK_POLICIES.include?(@fallback_policy)
119
125
 
126
+ raise ArgumentError.new("`synchronous` cannot be set unless `max_queue` is 0") if @synchronous && @max_queue > 0
127
+ raise ArgumentError.new("#{@fallback_policy} is not a valid fallback policy") unless FALLBACK_POLICIES.include?(@fallback_policy)
120
128
  raise ArgumentError.new("`max_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if @max_length < DEFAULT_MIN_POOL_SIZE
121
129
  raise ArgumentError.new("`max_threads` cannot be greater than #{DEFAULT_MAX_POOL_SIZE}") if @max_length > DEFAULT_MAX_POOL_SIZE
122
130
  raise ArgumentError.new("`min_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if @min_length < DEFAULT_MIN_POOL_SIZE
123
131
  raise ArgumentError.new("`min_threads` cannot be more than `max_threads`") if min_length > max_length
124
132
 
125
- self.auto_terminate = opts.fetch(:auto_terminate, true)
126
-
127
133
  @pool = [] # all workers
128
134
  @ready = [] # used as a stash (most idle worker is at the start)
129
135
  @queue = [] # used as queue
@@ -131,6 +137,7 @@ module Concurrent
131
137
  @scheduled_task_count = 0
132
138
  @completed_task_count = 0
133
139
  @largest_length = 0
140
+ @workers_counter = 0
134
141
  @ruby_pid = $$ # detects if Ruby has forked
135
142
 
136
143
  @gc_interval = opts.fetch(:gc_interval, @idletime / 2.0).to_i # undocumented
@@ -202,6 +209,8 @@ module Concurrent
202
209
  #
203
210
  # @!visibility private
204
211
  def ns_enqueue(*args, &task)
212
+ return false if @synchronous
213
+
205
214
  if !ns_limited_queue? || @queue.size < @max_queue
206
215
  @queue << [task, args]
207
216
  true
@@ -224,7 +233,8 @@ module Concurrent
224
233
  def ns_add_busy_worker
225
234
  return if @pool.size >= @max_length
226
235
 
227
- @pool << (worker = Worker.new(self))
236
+ @workers_counter += 1
237
+ @pool << (worker = Worker.new(self, @workers_counter))
228
238
  @largest_length = @pool.length if @pool.length > @largest_length
229
239
  worker
230
240
  end
@@ -284,6 +294,7 @@ module Concurrent
284
294
  @scheduled_task_count = 0
285
295
  @completed_task_count = 0
286
296
  @largest_length = 0
297
+ @workers_counter = 0
287
298
  @ruby_pid = $$
288
299
  end
289
300
  end
@@ -292,11 +303,15 @@ module Concurrent
292
303
  class Worker
293
304
  include Concern::Logging
294
305
 
295
- def initialize(pool)
306
+ def initialize(pool, id)
296
307
  # instance variables accessed only under pool's lock so no need to sync here again
297
308
  @queue = Queue.new
298
309
  @pool = pool
299
310
  @thread = create_worker @queue, pool, pool.idletime
311
+
312
+ if @thread.respond_to?(:name=)
313
+ @thread.name = [pool.name, 'worker', id].compact.join('-')
314
+ end
300
315
  end
301
316
 
302
317
  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)