concurrent-ruby 1.1.4 → 1.1.8

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 (131) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +51 -0
  3. data/Gemfile +11 -8
  4. data/{LICENSE.md → LICENSE.txt} +18 -20
  5. data/README.md +40 -5
  6. data/Rakefile +52 -64
  7. data/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java +9 -8
  8. data/lib/{concurrent-ruby.rb → concurrent-ruby/concurrent-ruby.rb} +0 -0
  9. data/lib/{concurrent.rb → concurrent-ruby/concurrent.rb} +0 -0
  10. data/lib/{concurrent → concurrent-ruby/concurrent}/agent.rb +0 -0
  11. data/lib/{concurrent → concurrent-ruby/concurrent}/array.rb +9 -9
  12. data/lib/{concurrent → concurrent-ruby/concurrent}/async.rb +23 -20
  13. data/lib/{concurrent → concurrent-ruby/concurrent}/atom.rb +1 -1
  14. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/abstract_thread_local_var.rb +0 -0
  15. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_boolean.rb +2 -2
  16. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_fixnum.rb +2 -2
  17. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_markable_reference.rb +0 -0
  18. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_reference.rb +0 -0
  19. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/count_down_latch.rb +1 -1
  20. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/cyclic_barrier.rb +0 -0
  21. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/event.rb +0 -0
  22. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/java_count_down_latch.rb +0 -0
  23. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/java_thread_local_var.rb +0 -0
  24. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_atomic_boolean.rb +0 -0
  25. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_atomic_fixnum.rb +0 -0
  26. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_count_down_latch.rb +0 -0
  27. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_semaphore.rb +0 -0
  28. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/read_write_lock.rb +0 -0
  29. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/reentrant_read_write_lock.rb +0 -0
  30. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/ruby_thread_local_var.rb +60 -40
  31. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/semaphore.rb +0 -0
  32. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/thread_local_var.rb +1 -1
  33. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic_reference/mutex_atomic.rb +0 -0
  34. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic_reference/numeric_cas_wrapper.rb +0 -0
  35. data/lib/{concurrent → concurrent-ruby/concurrent}/atomics.rb +0 -0
  36. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/copy_on_notify_observer_set.rb +0 -0
  37. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/copy_on_write_observer_set.rb +0 -0
  38. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/java_non_concurrent_priority_queue.rb +0 -0
  39. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/lock_free_stack.rb +1 -1
  40. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/atomic_reference_map_backend.rb +0 -0
  41. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/mri_map_backend.rb +1 -1
  42. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/non_concurrent_map_backend.rb +0 -0
  43. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/synchronized_map_backend.rb +0 -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 +0 -0
  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 +13 -16
  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 +4 -4
  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 +1 -1
  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 +0 -0
  89. data/lib/{concurrent → concurrent-ruby/concurrent}/promises.rb +348 -117
  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 +5 -5
  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 +12 -0
  98. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/condition.rb +2 -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 +1 -0
  101. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/lock.rb +2 -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 +1 -0
  104. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/mutex_lockable_object.rb +0 -0
  105. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/object.rb +46 -20
  106. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/rbx_lockable_object.rb +0 -0
  107. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/rbx_object.rb +1 -0
  108. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/truffleruby_object.rb +1 -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 +0 -0
  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 +129 -129
  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 -4
@@ -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
@@ -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