concurrent-ruby 1.0.5 → 1.1.10
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +155 -0
- data/Gemfile +37 -0
- data/LICENSE.txt +18 -18
- data/README.md +260 -103
- data/Rakefile +329 -0
- data/ext/concurrent-ruby/ConcurrentRubyService.java +17 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java +175 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/JRubyMapBackendLibrary.java +248 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicBooleanLibrary.java +93 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java +113 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java +189 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java +307 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMap.java +31 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java +3863 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/LongAdder.java +203 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java +342 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/ConcurrentHashMapV8.java +3800 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/LongAdder.java +204 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/Striped64.java +291 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166y/ThreadLocalRandom.java +199 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/agent.rb +7 -7
- data/lib/concurrent-ruby/concurrent/array.rb +66 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/async.rb +28 -24
- data/lib/{concurrent → concurrent-ruby/concurrent}/atom.rb +10 -10
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_boolean.rb +26 -22
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_fixnum.rb +27 -23
- data/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb +164 -0
- data/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb +205 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/count_down_latch.rb +7 -7
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/cyclic_barrier.rb +1 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/event.rb +3 -3
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/java_count_down_latch.rb +9 -6
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_atomic_boolean.rb +2 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_count_down_latch.rb +1 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_semaphore.rb +18 -2
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/read_write_lock.rb +2 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/reentrant_read_write_lock.rb +7 -7
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/ruby_thread_local_var.rb +60 -40
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/semaphore.rb +34 -13
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/thread_local_var.rb +8 -8
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic_reference/mutex_atomic.rb +3 -8
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic_reference/numeric_cas_wrapper.rb +1 -1
- data/lib/concurrent-ruby/concurrent/atomics.rb +10 -0
- data/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb +158 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/atomic_reference_map_backend.rb +3 -3
- data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/mri_map_backend.rb +1 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/non_concurrent_map_backend.rb +1 -2
- data/lib/concurrent-ruby/concurrent/collection/map/truffleruby_map_backend.rb +14 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/collection/non_concurrent_priority_queue.rb +30 -30
- data/lib/{concurrent → concurrent-ruby/concurrent}/collection/ruby_non_concurrent_priority_queue.rb +11 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/concern/dereferenceable.rb +3 -3
- data/lib/{concurrent → concurrent-ruby/concurrent}/concern/logging.rb +6 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/concern/observable.rb +7 -7
- data/lib/concurrent-ruby/concurrent/concurrent_ruby.jar +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/configuration.rb +15 -15
- data/lib/{concurrent → concurrent-ruby/concurrent}/constants.rb +1 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/dataflow.rb +2 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/delay.rb +9 -7
- data/lib/{concurrent → concurrent-ruby/concurrent}/exchanger.rb +21 -25
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/abstract_executor_service.rb +35 -38
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/cached_thread_pool.rb +5 -5
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/executor_service.rb +17 -17
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/fixed_thread_pool.rb +47 -33
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/java_executor_service.rb +20 -17
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/java_single_thread_executor.rb +4 -3
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/java_thread_pool_executor.rb +29 -9
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/ruby_executor_service.rb +10 -6
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/ruby_single_thread_executor.rb +0 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/ruby_thread_pool_executor.rb +46 -42
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/safe_task_executor.rb +5 -5
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/simple_executor_service.rb +1 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/single_thread_executor.rb +3 -2
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/thread_pool_executor.rb +7 -6
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/timer_set.rb +14 -17
- data/lib/{concurrent → concurrent-ruby/concurrent}/future.rb +4 -1
- data/lib/concurrent-ruby/concurrent/hash.rb +59 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/immutable_struct.rb +9 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/ivar.rb +5 -6
- data/lib/concurrent-ruby/concurrent/map.rb +346 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/maybe.rb +1 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/mutable_struct.rb +27 -16
- data/lib/{concurrent → concurrent-ruby/concurrent}/mvar.rb +2 -2
- data/lib/{concurrent → concurrent-ruby/concurrent}/promise.rb +54 -21
- data/lib/concurrent-ruby/concurrent/promises.rb +2167 -0
- data/lib/concurrent-ruby/concurrent/re_include.rb +58 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/scheduled_task.rb +29 -16
- data/lib/concurrent-ruby/concurrent/set.rb +74 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/settable_struct.rb +12 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/abstract_lockable_object.rb +5 -5
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/abstract_struct.rb +18 -4
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/condition.rb +2 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/jruby_object.rb +1 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/lock.rb +2 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/lockable_object.rb +8 -10
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/mri_object.rb +1 -0
- data/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb +88 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/object.rb +53 -23
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/rbx_lockable_object.rb +6 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/rbx_object.rb +1 -0
- data/lib/concurrent-ruby/concurrent/synchronization/truffleruby_object.rb +47 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/volatile.rb +11 -9
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization.rb +4 -5
- data/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb +88 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/striped64.rb +9 -4
- data/lib/{concurrent → concurrent-ruby/concurrent}/timer_task.rb +15 -35
- data/lib/{concurrent → concurrent-ruby/concurrent}/tuple.rb +1 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/tvar.rb +21 -58
- data/lib/{concurrent → concurrent-ruby/concurrent}/utility/engine.rb +4 -4
- data/lib/concurrent-ruby/concurrent/utility/monotonic_time.rb +90 -0
- data/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb +79 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/utility/processor_counter.rb +5 -35
- data/lib/concurrent-ruby/concurrent/version.rb +3 -0
- data/lib/concurrent-ruby/concurrent-ruby.rb +5 -0
- data/lib/{concurrent.rb → concurrent-ruby/concurrent.rb} +24 -20
- metadata +149 -134
- data/lib/concurrent/array.rb +0 -39
- data/lib/concurrent/atomic/atomic_reference.rb +0 -51
- data/lib/concurrent/atomic_reference/concurrent_update_error.rb +0 -8
- data/lib/concurrent/atomic_reference/direct_update.rb +0 -81
- data/lib/concurrent/atomic_reference/jruby+truffle.rb +0 -2
- data/lib/concurrent/atomic_reference/jruby.rb +0 -16
- data/lib/concurrent/atomic_reference/rbx.rb +0 -22
- data/lib/concurrent/atomic_reference/ruby.rb +0 -32
- data/lib/concurrent/atomics.rb +0 -53
- data/lib/concurrent/edge.rb +0 -26
- data/lib/concurrent/hash.rb +0 -36
- data/lib/concurrent/lazy_register.rb +0 -81
- data/lib/concurrent/map.rb +0 -240
- data/lib/concurrent/synchronization/mri_lockable_object.rb +0 -71
- data/lib/concurrent/synchronization/truffle_lockable_object.rb +0 -9
- data/lib/concurrent/synchronization/truffle_object.rb +0 -31
- data/lib/concurrent/thread_safe/util/array_hash_rbx.rb +0 -30
- data/lib/concurrent/utility/at_exit.rb +0 -97
- data/lib/concurrent/utility/monotonic_time.rb +0 -58
- data/lib/concurrent/utility/native_extension_loader.rb +0 -73
- data/lib/concurrent/version.rb +0 -4
- /data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/abstract_thread_local_var.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/java_thread_local_var.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_atomic_fixnum.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/collection/copy_on_notify_observer_set.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/collection/copy_on_write_observer_set.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/collection/java_non_concurrent_priority_queue.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/synchronized_map_backend.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/concern/deprecation.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/concern/obligation.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/errors.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/executor/immediate_executor.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/executor/indirect_immediate_executor.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/executor/serial_executor_service.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/executor/serialized_execution.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/executor/serialized_execution_delegator.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/executors.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/options.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/abstract_object.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/jruby_lockable_object.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/synchronized_delegator.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/adder.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/cheap_lockable.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/power_of_two_tuple.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/volatile.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/xor_shift_random.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby/concurrent}/utility/native_integer.rb +0 -0
@@ -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(
|
23
|
+
def initialize(opts = {}, &block)
|
21
24
|
super(&nil)
|
22
|
-
synchronize
|
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,38 +65,41 @@ module Concurrent
|
|
54
65
|
|
55
66
|
# @!macro executor_service_method_auto_terminate_question
|
56
67
|
def auto_terminate?
|
57
|
-
synchronize {
|
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
|
-
|
73
|
+
deprecated "Method #auto_terminate= has no effect. Set :auto_terminate option when executor is initialized."
|
63
74
|
end
|
64
75
|
|
65
76
|
private
|
66
77
|
|
67
|
-
#
|
68
|
-
# reaches `max_queue`.
|
78
|
+
# Returns an action which executes the `fallback_policy` once the queue
|
79
|
+
# size reaches `max_queue`. The reason for the indirection of an action
|
80
|
+
# is so that the work can be deferred outside of synchronization.
|
69
81
|
#
|
70
82
|
# @param [Array] args the arguments to the task which is being handled.
|
71
83
|
#
|
72
84
|
# @!visibility private
|
73
|
-
def
|
85
|
+
def fallback_action(*args)
|
74
86
|
case fallback_policy
|
75
87
|
when :abort
|
76
|
-
raise RejectedExecutionError
|
88
|
+
lambda { raise RejectedExecutionError }
|
77
89
|
when :discard
|
78
|
-
false
|
90
|
+
lambda { false }
|
79
91
|
when :caller_runs
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
92
|
+
lambda {
|
93
|
+
begin
|
94
|
+
yield(*args)
|
95
|
+
rescue => ex
|
96
|
+
# let it fail
|
97
|
+
log DEBUG, ex
|
98
|
+
end
|
99
|
+
true
|
100
|
+
}
|
87
101
|
else
|
88
|
-
fail "Unknown fallback policy #{fallback_policy}"
|
102
|
+
lambda { fail "Unknown fallback policy #{fallback_policy}" }
|
89
103
|
end
|
90
104
|
end
|
91
105
|
|
@@ -93,7 +107,7 @@ module Concurrent
|
|
93
107
|
raise NotImplementedError
|
94
108
|
end
|
95
109
|
|
96
|
-
# @!macro
|
110
|
+
# @!macro executor_service_method_ns_shutdown_execution
|
97
111
|
#
|
98
112
|
# Callback method called when an orderly shutdown has completed.
|
99
113
|
# The default behavior is to signal all waiting threads.
|
@@ -101,7 +115,7 @@ module Concurrent
|
|
101
115
|
# do nothing
|
102
116
|
end
|
103
117
|
|
104
|
-
# @!macro
|
118
|
+
# @!macro executor_service_method_ns_kill_execution
|
105
119
|
#
|
106
120
|
# Callback method called when the executor has been killed.
|
107
121
|
# The default behavior is to do nothing.
|
@@ -110,25 +124,8 @@ module Concurrent
|
|
110
124
|
end
|
111
125
|
|
112
126
|
def ns_auto_terminate?
|
113
|
-
|
127
|
+
@auto_terminate
|
114
128
|
end
|
115
129
|
|
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
130
|
end
|
134
131
|
end
|
@@ -26,7 +26,7 @@ module Concurrent
|
|
26
26
|
# @!macro thread_pool_options
|
27
27
|
class CachedThreadPool < ThreadPoolExecutor
|
28
28
|
|
29
|
-
# @!macro
|
29
|
+
# @!macro cached_thread_pool_method_initialize
|
30
30
|
#
|
31
31
|
# Create a new thread pool.
|
32
32
|
#
|
@@ -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:
|
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
|
55
|
-
@executor
|
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
|
@@ -4,7 +4,7 @@ module Concurrent
|
|
4
4
|
|
5
5
|
###################################################################
|
6
6
|
|
7
|
-
# @!macro
|
7
|
+
# @!macro executor_service_method_post
|
8
8
|
#
|
9
9
|
# Submit a task to the executor for asynchronous processing.
|
10
10
|
#
|
@@ -17,7 +17,7 @@ module Concurrent
|
|
17
17
|
#
|
18
18
|
# @raise [ArgumentError] if no task is given
|
19
19
|
|
20
|
-
# @!macro
|
20
|
+
# @!macro executor_service_method_left_shift
|
21
21
|
#
|
22
22
|
# Submit a task to the executor for asynchronous processing.
|
23
23
|
#
|
@@ -25,13 +25,13 @@ module Concurrent
|
|
25
25
|
#
|
26
26
|
# @return [self] returns itself
|
27
27
|
|
28
|
-
# @!macro
|
28
|
+
# @!macro executor_service_method_can_overflow_question
|
29
29
|
#
|
30
30
|
# Does the task queue have a maximum size?
|
31
31
|
#
|
32
32
|
# @return [Boolean] True if the task queue has a maximum size else false.
|
33
33
|
|
34
|
-
# @!macro
|
34
|
+
# @!macro executor_service_method_serialized_question
|
35
35
|
#
|
36
36
|
# Does this executor guarantee serialization of its operations?
|
37
37
|
#
|
@@ -41,7 +41,7 @@ module Concurrent
|
|
41
41
|
|
42
42
|
###################################################################
|
43
43
|
|
44
|
-
# @!macro
|
44
|
+
# @!macro executor_service_public_api
|
45
45
|
#
|
46
46
|
# @!method post(*args, &task)
|
47
47
|
# @!macro executor_service_method_post
|
@@ -57,23 +57,23 @@ module Concurrent
|
|
57
57
|
|
58
58
|
###################################################################
|
59
59
|
|
60
|
-
# @!macro
|
60
|
+
# @!macro executor_service_attr_reader_fallback_policy
|
61
61
|
# @return [Symbol] The fallback policy in effect. Either `:abort`, `:discard`, or `:caller_runs`.
|
62
62
|
|
63
|
-
# @!macro
|
63
|
+
# @!macro executor_service_method_shutdown
|
64
64
|
#
|
65
65
|
# Begin an orderly shutdown. Tasks already in the queue will be executed,
|
66
66
|
# but no new tasks will be accepted. Has no additional effect if the
|
67
67
|
# thread pool is not running.
|
68
68
|
|
69
|
-
# @!macro
|
69
|
+
# @!macro executor_service_method_kill
|
70
70
|
#
|
71
71
|
# Begin an immediate shutdown. In-progress tasks will be allowed to
|
72
72
|
# complete but enqueued tasks will be dismissed and no new tasks
|
73
73
|
# will be accepted. Has no additional effect if the thread pool is
|
74
74
|
# not running.
|
75
75
|
|
76
|
-
# @!macro
|
76
|
+
# @!macro executor_service_method_wait_for_termination
|
77
77
|
#
|
78
78
|
# Block until executor shutdown is complete or until `timeout` seconds have
|
79
79
|
# passed.
|
@@ -85,41 +85,41 @@ module Concurrent
|
|
85
85
|
#
|
86
86
|
# @return [Boolean] `true` if shutdown complete or false on `timeout`
|
87
87
|
|
88
|
-
# @!macro
|
88
|
+
# @!macro executor_service_method_running_question
|
89
89
|
#
|
90
90
|
# Is the executor running?
|
91
91
|
#
|
92
92
|
# @return [Boolean] `true` when running, `false` when shutting down or shutdown
|
93
93
|
|
94
|
-
# @!macro
|
94
|
+
# @!macro executor_service_method_shuttingdown_question
|
95
95
|
#
|
96
96
|
# Is the executor shuttingdown?
|
97
97
|
#
|
98
98
|
# @return [Boolean] `true` when not running and not shutdown, else `false`
|
99
99
|
|
100
|
-
# @!macro
|
100
|
+
# @!macro executor_service_method_shutdown_question
|
101
101
|
#
|
102
102
|
# Is the executor shutdown?
|
103
103
|
#
|
104
104
|
# @return [Boolean] `true` when shutdown, `false` when shutting down or running
|
105
105
|
|
106
|
-
# @!macro
|
106
|
+
# @!macro executor_service_method_auto_terminate_question
|
107
107
|
#
|
108
108
|
# Is the executor auto-terminate when the application exits?
|
109
109
|
#
|
110
110
|
# @return [Boolean] `true` when auto-termination is enabled else `false`.
|
111
111
|
|
112
|
-
# @!macro
|
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
|
###################################################################
|
121
121
|
|
122
|
-
# @!macro
|
122
|
+
# @!macro abstract_executor_service_public_api
|
123
123
|
#
|
124
124
|
# @!macro executor_service_public_api
|
125
125
|
#
|
@@ -3,44 +3,51 @@ require 'concurrent/executor/thread_pool_executor'
|
|
3
3
|
|
4
4
|
module Concurrent
|
5
5
|
|
6
|
-
# @!macro
|
6
|
+
# @!macro thread_pool_executor_constant_default_max_pool_size
|
7
7
|
# Default maximum number of threads that will be created in the pool.
|
8
8
|
|
9
|
-
# @!macro
|
9
|
+
# @!macro thread_pool_executor_constant_default_min_pool_size
|
10
10
|
# Default minimum number of threads that will be retained in the pool.
|
11
11
|
|
12
|
-
# @!macro
|
12
|
+
# @!macro thread_pool_executor_constant_default_max_queue_size
|
13
13
|
# Default maximum number of tasks that may be added to the task queue.
|
14
14
|
|
15
|
-
# @!macro
|
15
|
+
# @!macro thread_pool_executor_constant_default_thread_timeout
|
16
16
|
# Default maximum number of seconds a thread in the pool may remain idle
|
17
17
|
# before being reclaimed.
|
18
18
|
|
19
|
-
# @!macro
|
19
|
+
# @!macro thread_pool_executor_constant_default_synchronous
|
20
|
+
# Default value of the :synchronous option.
|
21
|
+
|
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.
|
22
25
|
|
23
|
-
# @!macro
|
26
|
+
# @!macro thread_pool_executor_attr_reader_min_length
|
24
27
|
# The minimum number of threads that may be retained in the pool.
|
25
28
|
# @return [Integer] The minimum number of threads that may be retained in the pool.
|
26
29
|
|
27
|
-
# @!macro
|
30
|
+
# @!macro thread_pool_executor_attr_reader_largest_length
|
28
31
|
# The largest number of threads that have been created in the pool since construction.
|
29
32
|
# @return [Integer] The largest number of threads that have been created in the pool since construction.
|
30
33
|
|
31
|
-
# @!macro
|
34
|
+
# @!macro thread_pool_executor_attr_reader_scheduled_task_count
|
32
35
|
# The number of tasks that have been scheduled for execution on the pool since construction.
|
33
36
|
# @return [Integer] The number of tasks that have been scheduled for execution on the pool since construction.
|
34
37
|
|
35
|
-
# @!macro
|
38
|
+
# @!macro thread_pool_executor_attr_reader_completed_task_count
|
36
39
|
# The number of tasks that have been completed by the pool since construction.
|
37
40
|
# @return [Integer] The number of tasks that have been completed by the pool since construction.
|
38
41
|
|
39
|
-
# @!macro
|
42
|
+
# @!macro thread_pool_executor_attr_reader_idletime
|
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
|
|
43
|
-
# @!macro
|
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
|
+
|
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
|
46
53
|
# accordance with the configured `fallback_policy`.
|
@@ -49,26 +56,33 @@ module Concurrent
|
|
49
56
|
# When the queue size reaches `max_queue` subsequent tasks will be rejected in
|
50
57
|
# accordance with the configured `fallback_policy`.
|
51
58
|
|
52
|
-
# @!macro
|
59
|
+
# @!macro thread_pool_executor_attr_reader_length
|
53
60
|
# The number of threads currently in the pool.
|
54
61
|
# @return [Integer] The number of threads currently in the pool.
|
55
62
|
|
56
|
-
# @!macro
|
63
|
+
# @!macro thread_pool_executor_attr_reader_queue_length
|
57
64
|
# The number of tasks in the queue awaiting execution.
|
58
65
|
# @return [Integer] The number of tasks in the queue awaiting execution.
|
59
66
|
|
60
|
-
# @!macro
|
67
|
+
# @!macro thread_pool_executor_attr_reader_remaining_capacity
|
61
68
|
# Number of tasks that may be enqueued before reaching `max_queue` and rejecting
|
62
69
|
# new tasks. A value of -1 indicates that the queue may grow without bound.
|
63
70
|
#
|
64
71
|
# @return [Integer] Number of tasks that may be enqueued before reaching `max_queue` and rejecting
|
65
72
|
# new tasks. A value of -1 indicates that the queue may grow without bound.
|
66
73
|
|
74
|
+
# @!macro thread_pool_executor_method_prune_pool
|
75
|
+
# Prune the thread pool of unneeded threads
|
76
|
+
#
|
77
|
+
# What is being pruned is controlled by the min_threads and idletime
|
78
|
+
# parameters passed at pool creation time
|
79
|
+
#
|
80
|
+
# This is a no-op on some pool implementation (e.g. the Java one). The Ruby
|
81
|
+
# pool will auto-prune each time a new job is posted. You will need to call
|
82
|
+
# this method explicitely in case your application post jobs in bursts (a
|
83
|
+
# lot of jobs and then nothing for long periods)
|
67
84
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
# @!macro [new] thread_pool_executor_public_api
|
85
|
+
# @!macro thread_pool_executor_public_api
|
72
86
|
#
|
73
87
|
# @!macro abstract_executor_service_public_api
|
74
88
|
#
|
@@ -104,23 +118,27 @@ module Concurrent
|
|
104
118
|
#
|
105
119
|
# @!method can_overflow?
|
106
120
|
# @!macro executor_service_method_can_overflow_question
|
121
|
+
#
|
122
|
+
# @!method prune_pool
|
123
|
+
# @!macro thread_pool_executor_method_prune_pool
|
107
124
|
|
108
125
|
|
109
126
|
|
110
127
|
|
111
|
-
# @!macro
|
128
|
+
# @!macro thread_pool_options
|
112
129
|
#
|
113
130
|
# **Thread Pool Options**
|
114
131
|
#
|
115
132
|
# Thread pools support several configuration options:
|
116
133
|
#
|
117
134
|
# * `idletime`: The number of seconds that a thread may be idle before being reclaimed.
|
135
|
+
# * `name`: The name of the executor (optional). Printed in the executor's `#to_s` output and
|
136
|
+
# a `<name>-worker-<id>` name is given to its threads if supported by used Ruby
|
137
|
+
# implementation. `<id>` is uniq for each thread.
|
118
138
|
# * `max_queue`: The maximum number of tasks that may be waiting in the work queue at
|
119
139
|
# any one time. When the queue size reaches `max_queue` and no new threads can be created,
|
120
140
|
# subsequent tasks will be rejected in accordance with the configured `fallback_policy`.
|
121
|
-
# * `auto_terminate`: When true (default)
|
122
|
-
# will stop the thread pool when the application exits. See below for more information
|
123
|
-
# on shutting down thread pools.
|
141
|
+
# * `auto_terminate`: When true (default), the threads started will be marked as daemon.
|
124
142
|
# * `fallback_policy`: The policy defining how rejected tasks are handled.
|
125
143
|
#
|
126
144
|
# Three fallback policies are supported:
|
@@ -145,16 +163,12 @@ module Concurrent
|
|
145
163
|
#
|
146
164
|
# On some runtime platforms (most notably the JVM) the application will not
|
147
165
|
# exit until all thread pools have been shutdown. To prevent applications from
|
148
|
-
# "hanging" on exit all
|
149
|
-
#
|
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.
|
166
|
+
# "hanging" on exit, all threads can be marked as daemon according to the
|
167
|
+
# `:auto_terminate` option.
|
154
168
|
#
|
155
169
|
# ```ruby
|
156
|
-
# pool1 = Concurrent::FixedThreadPool.new(5) #
|
157
|
-
# pool2 = Concurrent::FixedThreadPool.new(5, auto_terminate: false) #
|
170
|
+
# pool1 = Concurrent::FixedThreadPool.new(5) # threads will be marked as daemon
|
171
|
+
# pool2 = Concurrent::FixedThreadPool.new(5, auto_terminate: false) # mark threads as non-daemon
|
158
172
|
# ```
|
159
173
|
#
|
160
174
|
# @note Failure to properly shutdown a thread pool can lead to unpredictable results.
|
@@ -163,13 +177,13 @@ module Concurrent
|
|
163
177
|
# @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html Java Tutorials: Thread Pools
|
164
178
|
# @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html Java Executors class
|
165
179
|
# @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html Java ExecutorService interface
|
166
|
-
# @see
|
180
|
+
# @see https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#setDaemon-boolean-
|
167
181
|
|
168
182
|
|
169
183
|
|
170
184
|
|
171
185
|
|
172
|
-
# @!macro
|
186
|
+
# @!macro fixed_thread_pool
|
173
187
|
#
|
174
188
|
# A thread pool that reuses a fixed number of threads operating off an unbounded queue.
|
175
189
|
# At any point, at most `num_threads` will be active processing tasks. When all threads are busy new
|
@@ -182,7 +196,7 @@ module Concurrent
|
|
182
196
|
# @!macro thread_pool_options
|
183
197
|
class FixedThreadPool < ThreadPoolExecutor
|
184
198
|
|
185
|
-
# @!macro
|
199
|
+
# @!macro fixed_thread_pool_method_initialize
|
186
200
|
#
|
187
201
|
# Create a new thread pool.
|
188
202
|
#
|
@@ -18,15 +18,10 @@ if Concurrent.on_jruby?
|
|
18
18
|
}.freeze
|
19
19
|
private_constant :FALLBACK_POLICY_CLASSES
|
20
20
|
|
21
|
-
def initialize(*args, &block)
|
22
|
-
super
|
23
|
-
ns_make_executor_runnable
|
24
|
-
end
|
25
|
-
|
26
21
|
def post(*args, &task)
|
27
22
|
raise ArgumentError.new('no block given') unless block_given?
|
28
|
-
return
|
29
|
-
@executor.
|
23
|
+
return fallback_action(*args, &task).call unless running?
|
24
|
+
@executor.submit Job.new(args, task)
|
30
25
|
true
|
31
26
|
rescue Java::JavaUtilConcurrent::RejectedExecutionException
|
32
27
|
raise RejectedExecutionError
|
@@ -43,7 +38,6 @@ if Concurrent.on_jruby?
|
|
43
38
|
|
44
39
|
def shutdown
|
45
40
|
synchronize do
|
46
|
-
self.ns_auto_terminate = false
|
47
41
|
@executor.shutdown
|
48
42
|
nil
|
49
43
|
end
|
@@ -51,7 +45,6 @@ if Concurrent.on_jruby?
|
|
51
45
|
|
52
46
|
def kill
|
53
47
|
synchronize do
|
54
|
-
self.ns_auto_terminate = false
|
55
48
|
@executor.shutdownNow
|
56
49
|
nil
|
57
50
|
end
|
@@ -75,14 +68,6 @@ if Concurrent.on_jruby?
|
|
75
68
|
@executor.isShutdown || @executor.isTerminated
|
76
69
|
end
|
77
70
|
|
78
|
-
def ns_make_executor_runnable
|
79
|
-
if !defined?(@executor.submit_runnable)
|
80
|
-
@executor.class.class_eval do
|
81
|
-
java_alias :submit_runnable, :submit, [java.lang.Runnable.java_class]
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
71
|
class Job
|
87
72
|
include Runnable
|
88
73
|
def initialize(args, block)
|
@@ -96,5 +81,23 @@ if Concurrent.on_jruby?
|
|
96
81
|
end
|
97
82
|
private_constant :Job
|
98
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
|
+
|
99
102
|
end
|
100
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)
|
@@ -87,15 +93,21 @@ if Concurrent.on_jruby?
|
|
87
93
|
super && !@executor.isTerminating
|
88
94
|
end
|
89
95
|
|
96
|
+
# @!macro thread_pool_executor_method_prune_pool
|
97
|
+
def prune_pool
|
98
|
+
end
|
99
|
+
|
90
100
|
private
|
91
101
|
|
92
102
|
def ns_initialize(opts)
|
93
|
-
min_length
|
94
|
-
max_length
|
95
|
-
idletime
|
96
|
-
@max_queue
|
103
|
+
min_length = opts.fetch(:min_threads, DEFAULT_MIN_POOL_SIZE).to_i
|
104
|
+
max_length = opts.fetch(:max_threads, DEFAULT_MAX_POOL_SIZE).to_i
|
105
|
+
idletime = opts.fetch(:idletime, DEFAULT_THREAD_IDLETIMEOUT).to_i
|
106
|
+
@max_queue = opts.fetch(:max_queue, DEFAULT_MAX_QUEUE_SIZE).to_i
|
107
|
+
@synchronous = opts.fetch(:synchronous, DEFAULT_SYNCHRONOUS)
|
97
108
|
@fallback_policy = opts.fetch(:fallback_policy, :abort)
|
98
109
|
|
110
|
+
raise ArgumentError.new("`synchronous` cannot be set unless `max_queue` is 0") if @synchronous && @max_queue > 0
|
99
111
|
raise ArgumentError.new("`max_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if max_length < DEFAULT_MIN_POOL_SIZE
|
100
112
|
raise ArgumentError.new("`max_threads` cannot be greater than #{DEFAULT_MAX_POOL_SIZE}") if max_length > DEFAULT_MAX_POOL_SIZE
|
101
113
|
raise ArgumentError.new("`min_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if min_length < DEFAULT_MIN_POOL_SIZE
|
@@ -103,18 +115,26 @@ if Concurrent.on_jruby?
|
|
103
115
|
raise ArgumentError.new("#{fallback_policy} is not a valid fallback policy") unless FALLBACK_POLICY_CLASSES.include?(@fallback_policy)
|
104
116
|
|
105
117
|
if @max_queue == 0
|
106
|
-
|
118
|
+
if @synchronous
|
119
|
+
queue = java.util.concurrent.SynchronousQueue.new
|
120
|
+
else
|
121
|
+
queue = java.util.concurrent.LinkedBlockingQueue.new
|
122
|
+
end
|
107
123
|
else
|
108
124
|
queue = java.util.concurrent.LinkedBlockingQueue.new(@max_queue)
|
109
125
|
end
|
110
126
|
|
111
127
|
@executor = java.util.concurrent.ThreadPoolExecutor.new(
|
112
|
-
|
113
|
-
|
114
|
-
|
128
|
+
min_length,
|
129
|
+
max_length,
|
130
|
+
idletime,
|
131
|
+
java.util.concurrent.TimeUnit::SECONDS,
|
132
|
+
queue,
|
133
|
+
DaemonThreadFactory.new(ns_auto_terminate?),
|
134
|
+
FALLBACK_POLICY_CLASSES[@fallback_policy].new)
|
115
135
|
|
116
|
-
self.auto_terminate = opts.fetch(:auto_terminate, true)
|
117
136
|
end
|
118
137
|
end
|
138
|
+
|
119
139
|
end
|
120
140
|
end
|
@@ -16,10 +16,16 @@ module Concurrent
|
|
16
16
|
|
17
17
|
def post(*args, &task)
|
18
18
|
raise ArgumentError.new('no block given') unless block_given?
|
19
|
-
synchronize
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
deferred_action = synchronize {
|
20
|
+
if running?
|
21
|
+
ns_execute(*args, &task)
|
22
|
+
else
|
23
|
+
fallback_action(*args, &task)
|
24
|
+
end
|
25
|
+
}
|
26
|
+
if deferred_action
|
27
|
+
deferred_action.call
|
28
|
+
else
|
23
29
|
true
|
24
30
|
end
|
25
31
|
end
|
@@ -27,7 +33,6 @@ module Concurrent
|
|
27
33
|
def shutdown
|
28
34
|
synchronize do
|
29
35
|
break unless running?
|
30
|
-
self.ns_auto_terminate = false
|
31
36
|
stop_event.set
|
32
37
|
ns_shutdown_execution
|
33
38
|
end
|
@@ -37,7 +42,6 @@ module Concurrent
|
|
37
42
|
def kill
|
38
43
|
synchronize do
|
39
44
|
break if shutdown?
|
40
|
-
self.ns_auto_terminate = false
|
41
45
|
stop_event.set
|
42
46
|
ns_kill_execution
|
43
47
|
stopped_event.set
|