concurrent-ruby 0.9.2 → 1.0.0.pre1
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 +4 -4
- data/CHANGELOG.md +15 -1
- data/README.md +67 -68
- data/lib/concurrent.rb +14 -1
- data/lib/concurrent/array.rb +38 -0
- data/lib/concurrent/async.rb +0 -17
- data/lib/concurrent/atomic/abstract_thread_local_var.rb +40 -0
- data/lib/concurrent/atomic/atomic_boolean.rb +81 -118
- data/lib/concurrent/atomic/atomic_fixnum.rb +98 -162
- data/lib/concurrent/atomic/atomic_reference.rb +0 -7
- data/lib/concurrent/atomic/count_down_latch.rb +62 -103
- data/lib/concurrent/atomic/cyclic_barrier.rb +2 -0
- data/lib/concurrent/atomic/java_count_down_latch.rb +39 -0
- data/lib/concurrent/atomic/java_thread_local_var.rb +50 -0
- data/lib/concurrent/atomic/mutex_atomic_boolean.rb +60 -0
- data/lib/concurrent/atomic/mutex_atomic_fixnum.rb +91 -0
- data/lib/concurrent/atomic/mutex_count_down_latch.rb +43 -0
- data/lib/concurrent/atomic/mutex_semaphore.rb +115 -0
- data/lib/concurrent/atomic/ruby_thread_local_var.rb +172 -0
- data/lib/concurrent/atomic/semaphore.rb +84 -178
- data/lib/concurrent/atomic/thread_local_var.rb +63 -294
- data/lib/concurrent/atomic_reference/mutex_atomic.rb +14 -8
- data/lib/concurrent/atomics.rb +0 -33
- data/lib/concurrent/collection/java_non_concurrent_priority_queue.rb +84 -0
- data/lib/concurrent/collection/map/atomic_reference_map_backend.rb +921 -0
- data/lib/concurrent/collection/map/mri_map_backend.rb +66 -0
- data/lib/concurrent/collection/map/non_concurrent_map_backend.rb +142 -0
- data/lib/concurrent/collection/map/synchronized_map_backend.rb +86 -0
- data/lib/concurrent/collection/non_concurrent_priority_queue.rb +143 -0
- data/lib/concurrent/collection/ruby_non_concurrent_priority_queue.rb +150 -0
- data/lib/concurrent/concern/logging.rb +1 -1
- data/lib/concurrent/concern/obligation.rb +0 -12
- data/lib/concurrent/configuration.rb +18 -148
- data/lib/concurrent/delay.rb +5 -4
- data/lib/concurrent/exchanger.rb +327 -41
- data/lib/concurrent/executor/abstract_executor_service.rb +134 -0
- data/lib/concurrent/executor/executor.rb +4 -29
- data/lib/concurrent/executor/executor_service.rb +23 -359
- data/lib/concurrent/executor/immediate_executor.rb +3 -2
- data/lib/concurrent/executor/java_executor_service.rb +100 -0
- data/lib/concurrent/executor/java_single_thread_executor.rb +3 -2
- data/lib/concurrent/executor/java_thread_pool_executor.rb +3 -4
- data/lib/concurrent/executor/ruby_executor_service.rb +72 -0
- data/lib/concurrent/executor/ruby_single_thread_executor.rb +7 -5
- data/lib/concurrent/executor/ruby_thread_pool_executor.rb +3 -11
- data/lib/concurrent/executor/safe_task_executor.rb +1 -1
- data/lib/concurrent/executor/serial_executor_service.rb +34 -0
- data/lib/concurrent/executor/serialized_execution.rb +8 -31
- data/lib/concurrent/executor/serialized_execution_delegator.rb +28 -0
- data/lib/concurrent/executor/simple_executor_service.rb +1 -10
- data/lib/concurrent/executor/timer_set.rb +4 -8
- data/lib/concurrent/executors.rb +13 -2
- data/lib/concurrent/future.rb +2 -2
- data/lib/concurrent/hash.rb +35 -0
- data/lib/concurrent/ivar.rb +9 -14
- data/lib/concurrent/map.rb +178 -0
- data/lib/concurrent/promise.rb +2 -2
- data/lib/concurrent/scheduled_task.rb +9 -69
- data/lib/concurrent/thread_safe/synchronized_delegator.rb +50 -0
- data/lib/concurrent/thread_safe/util.rb +23 -0
- data/lib/concurrent/thread_safe/util/adder.rb +71 -0
- data/lib/concurrent/thread_safe/util/array_hash_rbx.rb +28 -0
- data/lib/concurrent/thread_safe/util/cheap_lockable.rb +115 -0
- data/lib/concurrent/thread_safe/util/power_of_two_tuple.rb +37 -0
- data/lib/concurrent/thread_safe/util/striped64.rb +236 -0
- data/lib/concurrent/thread_safe/util/volatile.rb +73 -0
- data/lib/concurrent/thread_safe/util/xor_shift_random.rb +48 -0
- data/lib/concurrent/timer_task.rb +3 -3
- data/lib/concurrent/tuple.rb +86 -0
- data/lib/concurrent/version.rb +2 -2
- metadata +37 -10
- data/lib/concurrent/atomic/condition.rb +0 -78
- data/lib/concurrent/collection/priority_queue.rb +0 -360
- data/lib/concurrent/utilities.rb +0 -5
- data/lib/concurrent/utility/timeout.rb +0 -39
- data/lib/concurrent/utility/timer.rb +0 -26
- data/lib/concurrent_ruby.rb +0 -2
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'concurrent/errors'
|
2
|
+
require 'concurrent/executor/executor_service'
|
3
|
+
require 'concurrent/synchronization/object'
|
4
|
+
require 'concurrent/utility/at_exit'
|
5
|
+
|
6
|
+
module Concurrent
|
7
|
+
|
8
|
+
# @!macro abstract_executor_service_public_api
|
9
|
+
# @!visibility private
|
10
|
+
class AbstractExecutorService < Synchronization::Object
|
11
|
+
include ExecutorService
|
12
|
+
|
13
|
+
# The set of possible fallback policies that may be set at thread pool creation.
|
14
|
+
FALLBACK_POLICIES = [:abort, :discard, :caller_runs].freeze
|
15
|
+
|
16
|
+
# @!macro executor_service_attr_reader_fallback_policy
|
17
|
+
attr_reader :fallback_policy
|
18
|
+
|
19
|
+
# Create a new thread pool.
|
20
|
+
def initialize(*args, &block)
|
21
|
+
super(&nil)
|
22
|
+
synchronize { ns_initialize(*args, &block) }
|
23
|
+
end
|
24
|
+
|
25
|
+
# @!macro executor_service_method_shutdown
|
26
|
+
def shutdown
|
27
|
+
raise NotImplementedError
|
28
|
+
end
|
29
|
+
|
30
|
+
# @!macro executor_service_method_kill
|
31
|
+
def kill
|
32
|
+
raise NotImplementedError
|
33
|
+
end
|
34
|
+
|
35
|
+
# @!macro executor_service_method_wait_for_termination
|
36
|
+
def wait_for_termination(timeout = nil)
|
37
|
+
raise NotImplementedError
|
38
|
+
end
|
39
|
+
|
40
|
+
# @!macro executor_service_method_running_question
|
41
|
+
def running?
|
42
|
+
synchronize { ns_running? }
|
43
|
+
end
|
44
|
+
|
45
|
+
# @!macro executor_service_method_shuttingdown_question
|
46
|
+
def shuttingdown?
|
47
|
+
synchronize { ns_shuttingdown? }
|
48
|
+
end
|
49
|
+
|
50
|
+
# @!macro executor_service_method_shutdown_question
|
51
|
+
def shutdown?
|
52
|
+
synchronize { ns_shutdown? }
|
53
|
+
end
|
54
|
+
|
55
|
+
# @!macro executor_service_method_auto_terminate_question
|
56
|
+
def auto_terminate?
|
57
|
+
synchronize { ns_auto_terminate? }
|
58
|
+
end
|
59
|
+
|
60
|
+
# @!macro executor_service_method_auto_terminate_setter
|
61
|
+
def auto_terminate=(value)
|
62
|
+
synchronize { self.ns_auto_terminate = value }
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
# Handler which executes the `fallback_policy` once the queue size
|
68
|
+
# reaches `max_queue`.
|
69
|
+
#
|
70
|
+
# @param [Array] args the arguments to the task which is being handled.
|
71
|
+
#
|
72
|
+
# @!visibility private
|
73
|
+
def handle_fallback(*args)
|
74
|
+
case fallback_policy
|
75
|
+
when :abort
|
76
|
+
raise RejectedExecutionError
|
77
|
+
when :discard
|
78
|
+
false
|
79
|
+
when :caller_runs
|
80
|
+
begin
|
81
|
+
yield(*args)
|
82
|
+
rescue => ex
|
83
|
+
# let it fail
|
84
|
+
log DEBUG, ex
|
85
|
+
end
|
86
|
+
true
|
87
|
+
else
|
88
|
+
fail "Unknown fallback policy #{fallback_policy}"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def ns_execute(*args, &task)
|
93
|
+
raise NotImplementedError
|
94
|
+
end
|
95
|
+
|
96
|
+
# @!macro [attach] executor_service_method_ns_shutdown_execution
|
97
|
+
#
|
98
|
+
# Callback method called when an orderly shutdown has completed.
|
99
|
+
# The default behavior is to signal all waiting threads.
|
100
|
+
def ns_shutdown_execution
|
101
|
+
# do nothing
|
102
|
+
end
|
103
|
+
|
104
|
+
# @!macro [attach] executor_service_method_ns_kill_execution
|
105
|
+
#
|
106
|
+
# Callback method called when the executor has been killed.
|
107
|
+
# The default behavior is to do nothing.
|
108
|
+
def ns_kill_execution
|
109
|
+
# do nothing
|
110
|
+
end
|
111
|
+
|
112
|
+
def ns_auto_terminate?
|
113
|
+
!!@auto_terminate
|
114
|
+
end
|
115
|
+
|
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
|
+
end
|
134
|
+
end
|
@@ -1,12 +1,10 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
require 'concurrent/executor/executor_service'
|
1
|
+
# This file has circular require issues. For now we assume all
|
2
|
+
# necessary dependencies have been required already.
|
4
3
|
|
5
4
|
module Concurrent
|
6
5
|
|
7
6
|
# @!visibility private
|
8
7
|
module Executor
|
9
|
-
extend Concern::Deprecation
|
10
8
|
|
11
9
|
# Get the requested `Executor` based on the values set in the options hash.
|
12
10
|
#
|
@@ -20,25 +18,8 @@ module Concurrent
|
|
20
18
|
#
|
21
19
|
# @!visibility private
|
22
20
|
def self.executor_from_options(opts = {}) # :nodoc:
|
23
|
-
|
24
|
-
|
25
|
-
if opts[:executor].nil?
|
26
|
-
nil
|
27
|
-
else
|
28
|
-
executor(opts[:executor])
|
29
|
-
end
|
30
|
-
when opts.key?(:operation) || opts.key?(:task)
|
31
|
-
if opts[:operation] == true || opts[:task] == false
|
32
|
-
deprecated 'use `executor: :fast` instead'
|
33
|
-
return Concurrent.global_fast_executor
|
34
|
-
end
|
35
|
-
|
36
|
-
if opts[:operation] == false || opts[:task] == true
|
37
|
-
deprecated 'use `executor: :io` instead'
|
38
|
-
return Concurrent.global_io_executor
|
39
|
-
end
|
40
|
-
|
41
|
-
raise ArgumentError.new("executor '#{opts[:executor]}' not recognized")
|
21
|
+
if identifier = opts.fetch(:executor, nil)
|
22
|
+
executor(identifier)
|
42
23
|
else
|
43
24
|
nil
|
44
25
|
end
|
@@ -52,12 +33,6 @@ module Concurrent
|
|
52
33
|
Concurrent.global_io_executor
|
53
34
|
when :immediate
|
54
35
|
Concurrent.global_immediate_executor
|
55
|
-
when :operation
|
56
|
-
deprecated 'use `executor: :fast` instead'
|
57
|
-
Concurrent.global_fast_executor
|
58
|
-
when :task
|
59
|
-
deprecated 'use `executor: :io` instead'
|
60
|
-
Concurrent.global_io_executor
|
61
36
|
when Concurrent::ExecutorService
|
62
37
|
executor_identifier
|
63
38
|
else
|
@@ -1,12 +1,9 @@
|
|
1
|
-
require 'concurrent/errors'
|
2
|
-
require 'concurrent/concern/deprecation'
|
3
1
|
require 'concurrent/concern/logging'
|
4
|
-
require 'concurrent/atomic/event'
|
5
|
-
require 'concurrent/synchronization'
|
6
|
-
require 'concurrent/utility/at_exit'
|
7
2
|
|
8
3
|
module Concurrent
|
9
4
|
|
5
|
+
###################################################################
|
6
|
+
|
10
7
|
# @!macro [new] executor_service_method_post
|
11
8
|
#
|
12
9
|
# Submit a task to the executor for asynchronous processing.
|
@@ -42,9 +39,7 @@ module Concurrent
|
|
42
39
|
# will be post in the order they are received and no two operations may
|
43
40
|
# occur simultaneously. Else false.
|
44
41
|
|
45
|
-
|
46
|
-
|
47
|
-
|
42
|
+
###################################################################
|
48
43
|
|
49
44
|
# @!macro [new] executor_service_public_api
|
50
45
|
#
|
@@ -60,75 +55,7 @@ module Concurrent
|
|
60
55
|
# @!method serialized?
|
61
56
|
# @!macro executor_service_method_serialized_question
|
62
57
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
# @!macro executor_service_public_api
|
68
|
-
# @!visibility private
|
69
|
-
module ExecutorService
|
70
|
-
include Concern::Logging
|
71
|
-
include Concern::Deprecation
|
72
|
-
|
73
|
-
# @!macro executor_service_method_post
|
74
|
-
def post(*args, &task)
|
75
|
-
raise NotImplementedError
|
76
|
-
end
|
77
|
-
|
78
|
-
# @!macro executor_service_method_left_shift
|
79
|
-
def <<(task)
|
80
|
-
post(&task)
|
81
|
-
self
|
82
|
-
end
|
83
|
-
|
84
|
-
# @!macro executor_service_method_can_overflow_question
|
85
|
-
#
|
86
|
-
# @note Always returns `false`
|
87
|
-
def can_overflow?
|
88
|
-
false
|
89
|
-
end
|
90
|
-
|
91
|
-
# @!macro executor_service_method_serialized_question
|
92
|
-
#
|
93
|
-
# @note Always returns `false`
|
94
|
-
def serialized?
|
95
|
-
false
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
# Indicates that the including `ExecutorService` guarantees
|
100
|
-
# that all operations will occur in the order they are post and that no
|
101
|
-
# two operations may occur simultaneously. This module provides no
|
102
|
-
# functionality and provides no guarantees. That is the responsibility
|
103
|
-
# of the including class. This module exists solely to allow the including
|
104
|
-
# object to be interrogated for its serialization status.
|
105
|
-
#
|
106
|
-
# @example
|
107
|
-
# class Foo
|
108
|
-
# include Concurrent::SerialExecutor
|
109
|
-
# end
|
110
|
-
#
|
111
|
-
# foo = Foo.new
|
112
|
-
#
|
113
|
-
# foo.is_a? Concurrent::ExecutorService #=> true
|
114
|
-
# foo.is_a? Concurrent::SerialExecutor #=> true
|
115
|
-
# foo.serialized? #=> true
|
116
|
-
#
|
117
|
-
# @!visibility private
|
118
|
-
module SerialExecutorService
|
119
|
-
include ExecutorService
|
120
|
-
|
121
|
-
# @!macro executor_service_method_serialized_question
|
122
|
-
#
|
123
|
-
# @note Always returns `true`
|
124
|
-
def serialized?
|
125
|
-
true
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
58
|
+
###################################################################
|
132
59
|
|
133
60
|
# @!macro [new] executor_service_attr_reader_fallback_policy
|
134
61
|
# @return [Symbol] The fallback policy in effect. Either `:abort`, `:discard`, or `:caller_runs`.
|
@@ -190,9 +117,7 @@ module Concurrent
|
|
190
117
|
#
|
191
118
|
# @return [Boolean] `true` when auto-termination is enabled else `false`.
|
192
119
|
|
193
|
-
|
194
|
-
|
195
|
-
|
120
|
+
###################################################################
|
196
121
|
|
197
122
|
# @!macro [new] abstract_executor_service_public_api
|
198
123
|
#
|
@@ -225,297 +150,36 @@ module Concurrent
|
|
225
150
|
# @!method auto_terminate=(value)
|
226
151
|
# @!macro executor_service_method_auto_terminate_setter
|
227
152
|
|
153
|
+
###################################################################
|
228
154
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
# @!macro abstract_executor_service_public_api
|
155
|
+
# @!macro executor_service_public_api
|
233
156
|
# @!visibility private
|
234
|
-
|
235
|
-
include
|
236
|
-
|
237
|
-
# The set of possible fallback policies that may be set at thread pool creation.
|
238
|
-
FALLBACK_POLICIES = [:abort, :discard, :caller_runs].freeze
|
239
|
-
|
240
|
-
# @!macro [attach] executor_service_attr_reader_fallback_policy
|
241
|
-
attr_reader :fallback_policy
|
242
|
-
|
243
|
-
# Create a new thread pool.
|
244
|
-
def initialize(*args, &block)
|
245
|
-
super(&nil)
|
246
|
-
synchronize { ns_initialize(*args, &block) }
|
247
|
-
end
|
248
|
-
|
249
|
-
# @!macro [attach] executor_service_method_shutdown
|
250
|
-
def shutdown
|
251
|
-
raise NotImplementedError
|
252
|
-
end
|
253
|
-
|
254
|
-
# @!macro [attach] executor_service_method_kill
|
255
|
-
def kill
|
256
|
-
raise NotImplementedError
|
257
|
-
end
|
157
|
+
module ExecutorService
|
158
|
+
include Concern::Logging
|
258
159
|
|
259
|
-
# @!macro
|
260
|
-
def
|
160
|
+
# @!macro executor_service_method_post
|
161
|
+
def post(*args, &task)
|
261
162
|
raise NotImplementedError
|
262
163
|
end
|
263
164
|
|
264
|
-
# @!macro
|
265
|
-
def
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
# @!macro [attach] executor_service_method_shuttingdown_question
|
270
|
-
def shuttingdown?
|
271
|
-
synchronize { ns_shuttingdown? }
|
272
|
-
end
|
273
|
-
|
274
|
-
# @!macro [attach] executor_service_method_shutdown_question
|
275
|
-
def shutdown?
|
276
|
-
synchronize { ns_shutdown? }
|
277
|
-
end
|
278
|
-
|
279
|
-
# @!macro [attach] executor_service_method_auto_terminate_question
|
280
|
-
def auto_terminate?
|
281
|
-
synchronize { ns_auto_terminate? }
|
282
|
-
end
|
283
|
-
|
284
|
-
# @!macro [attach] executor_service_method_auto_terminate_setter
|
285
|
-
def auto_terminate=(value)
|
286
|
-
synchronize { self.ns_auto_terminate = value }
|
287
|
-
end
|
288
|
-
|
289
|
-
protected
|
290
|
-
|
291
|
-
# Handler which executes the `fallback_policy` once the queue size
|
292
|
-
# reaches `max_queue`.
|
293
|
-
#
|
294
|
-
# @param [Array] args the arguments to the task which is being handled.
|
295
|
-
#
|
296
|
-
# @!visibility private
|
297
|
-
def handle_fallback(*args)
|
298
|
-
case fallback_policy
|
299
|
-
when :abort
|
300
|
-
raise RejectedExecutionError
|
301
|
-
when :discard
|
302
|
-
false
|
303
|
-
when :caller_runs
|
304
|
-
begin
|
305
|
-
yield(*args)
|
306
|
-
rescue => ex
|
307
|
-
# let it fail
|
308
|
-
log DEBUG, ex
|
309
|
-
end
|
310
|
-
true
|
311
|
-
else
|
312
|
-
fail "Unknown fallback policy #{fallback_policy}"
|
313
|
-
end
|
314
|
-
end
|
315
|
-
|
316
|
-
def execute(*args, &task)
|
317
|
-
raise NotImplementedError
|
165
|
+
# @!macro executor_service_method_left_shift
|
166
|
+
def <<(task)
|
167
|
+
post(&task)
|
168
|
+
self
|
318
169
|
end
|
319
170
|
|
320
|
-
# @!macro
|
171
|
+
# @!macro executor_service_method_can_overflow_question
|
321
172
|
#
|
322
|
-
#
|
323
|
-
|
324
|
-
|
325
|
-
# do nothing
|
173
|
+
# @note Always returns `false`
|
174
|
+
def can_overflow?
|
175
|
+
false
|
326
176
|
end
|
327
177
|
|
328
|
-
# @!macro
|
178
|
+
# @!macro executor_service_method_serialized_question
|
329
179
|
#
|
330
|
-
#
|
331
|
-
|
332
|
-
|
333
|
-
# do nothing
|
334
|
-
end
|
335
|
-
|
336
|
-
protected
|
337
|
-
|
338
|
-
def ns_auto_terminate?
|
339
|
-
!!@auto_terminate
|
340
|
-
end
|
341
|
-
|
342
|
-
def ns_auto_terminate=(value)
|
343
|
-
case value
|
344
|
-
when true
|
345
|
-
AtExit.add(self) { terminate_at_exit }
|
346
|
-
@auto_terminate = true
|
347
|
-
when false
|
348
|
-
AtExit.delete(self)
|
349
|
-
@auto_terminate = false
|
350
|
-
else
|
351
|
-
raise ArgumentError
|
352
|
-
end
|
353
|
-
end
|
354
|
-
|
355
|
-
def terminate_at_exit
|
356
|
-
kill # TODO be gentle first
|
357
|
-
wait_for_termination(10)
|
358
|
-
end
|
359
|
-
end
|
360
|
-
|
361
|
-
# @!macro abstract_executor_service_public_api
|
362
|
-
# @!visibility private
|
363
|
-
class RubyExecutorService < AbstractExecutorService
|
364
|
-
|
365
|
-
def initialize(*args, &block)
|
366
|
-
super
|
367
|
-
@stop_event = Event.new
|
368
|
-
@stopped_event = Event.new
|
369
|
-
ensure_ivar_visibility!
|
370
|
-
end
|
371
|
-
|
372
|
-
def post(*args, &task)
|
373
|
-
raise ArgumentError.new('no block given') unless block_given?
|
374
|
-
synchronize do
|
375
|
-
# If the executor is shut down, reject this task
|
376
|
-
return handle_fallback(*args, &task) unless running?
|
377
|
-
execute(*args, &task)
|
378
|
-
true
|
379
|
-
end
|
380
|
-
end
|
381
|
-
|
382
|
-
def shutdown
|
383
|
-
synchronize do
|
384
|
-
break unless running?
|
385
|
-
self.ns_auto_terminate = false
|
386
|
-
stop_event.set
|
387
|
-
shutdown_execution
|
388
|
-
end
|
389
|
-
true
|
390
|
-
end
|
391
|
-
|
392
|
-
def kill
|
393
|
-
synchronize do
|
394
|
-
break if shutdown?
|
395
|
-
self.ns_auto_terminate = false
|
396
|
-
stop_event.set
|
397
|
-
kill_execution
|
398
|
-
stopped_event.set
|
399
|
-
end
|
400
|
-
true
|
401
|
-
end
|
402
|
-
|
403
|
-
def wait_for_termination(timeout = nil)
|
404
|
-
stopped_event.wait(timeout)
|
405
|
-
end
|
406
|
-
|
407
|
-
protected
|
408
|
-
|
409
|
-
attr_reader :stop_event, :stopped_event
|
410
|
-
|
411
|
-
def shutdown_execution
|
412
|
-
stopped_event.set
|
413
|
-
end
|
414
|
-
|
415
|
-
def ns_running?
|
416
|
-
!stop_event.set?
|
417
|
-
end
|
418
|
-
|
419
|
-
def ns_shuttingdown?
|
420
|
-
!(ns_running? || ns_shutdown?)
|
421
|
-
end
|
422
|
-
|
423
|
-
def ns_shutdown?
|
424
|
-
stopped_event.set?
|
425
|
-
end
|
426
|
-
end
|
427
|
-
|
428
|
-
if Concurrent.on_jruby?
|
429
|
-
|
430
|
-
# @!macro abstract_executor_service_public_api
|
431
|
-
# @!visibility private
|
432
|
-
class JavaExecutorService < AbstractExecutorService
|
433
|
-
java_import 'java.lang.Runnable'
|
434
|
-
|
435
|
-
FALLBACK_POLICY_CLASSES = {
|
436
|
-
abort: java.util.concurrent.ThreadPoolExecutor::AbortPolicy,
|
437
|
-
discard: java.util.concurrent.ThreadPoolExecutor::DiscardPolicy,
|
438
|
-
caller_runs: java.util.concurrent.ThreadPoolExecutor::CallerRunsPolicy
|
439
|
-
}.freeze
|
440
|
-
private_constant :FALLBACK_POLICY_CLASSES
|
441
|
-
|
442
|
-
def initialize(*args, &block)
|
443
|
-
super
|
444
|
-
ns_make_executor_runnable
|
445
|
-
end
|
446
|
-
|
447
|
-
def post(*args, &task)
|
448
|
-
raise ArgumentError.new('no block given') unless block_given?
|
449
|
-
return handle_fallback(*args, &task) unless running?
|
450
|
-
@executor.submit_runnable Job.new(args, task)
|
451
|
-
true
|
452
|
-
rescue Java::JavaUtilConcurrent::RejectedExecutionException
|
453
|
-
raise RejectedExecutionError
|
454
|
-
end
|
455
|
-
|
456
|
-
def wait_for_termination(timeout = nil)
|
457
|
-
if timeout.nil?
|
458
|
-
ok = @executor.awaitTermination(60, java.util.concurrent.TimeUnit::SECONDS) until ok
|
459
|
-
true
|
460
|
-
else
|
461
|
-
@executor.awaitTermination(1000 * timeout, java.util.concurrent.TimeUnit::MILLISECONDS)
|
462
|
-
end
|
463
|
-
end
|
464
|
-
|
465
|
-
def shutdown
|
466
|
-
synchronize do
|
467
|
-
self.ns_auto_terminate = false
|
468
|
-
@executor.shutdown
|
469
|
-
nil
|
470
|
-
end
|
471
|
-
end
|
472
|
-
|
473
|
-
def kill
|
474
|
-
synchronize do
|
475
|
-
self.ns_auto_terminate = false
|
476
|
-
@executor.shutdownNow
|
477
|
-
nil
|
478
|
-
end
|
479
|
-
end
|
480
|
-
|
481
|
-
protected
|
482
|
-
|
483
|
-
def ns_running?
|
484
|
-
!(ns_shuttingdown? || ns_shutdown?)
|
485
|
-
end
|
486
|
-
|
487
|
-
def ns_shuttingdown?
|
488
|
-
if @executor.respond_to? :isTerminating
|
489
|
-
@executor.isTerminating
|
490
|
-
else
|
491
|
-
false
|
492
|
-
end
|
493
|
-
end
|
494
|
-
|
495
|
-
def ns_shutdown?
|
496
|
-
@executor.isShutdown || @executor.isTerminated
|
497
|
-
end
|
498
|
-
|
499
|
-
def ns_make_executor_runnable
|
500
|
-
if !defined?(@executor.submit_runnable)
|
501
|
-
@executor.class.class_eval do
|
502
|
-
java_alias :submit_runnable, :submit, [java.lang.Runnable.java_class]
|
503
|
-
end
|
504
|
-
end
|
505
|
-
end
|
506
|
-
|
507
|
-
class Job
|
508
|
-
include Runnable
|
509
|
-
def initialize(args, block)
|
510
|
-
@args = args
|
511
|
-
@block = block
|
512
|
-
end
|
513
|
-
|
514
|
-
def run
|
515
|
-
@block.call(*@args)
|
516
|
-
end
|
517
|
-
end
|
518
|
-
private_constant :Job
|
180
|
+
# @note Always returns `false`
|
181
|
+
def serialized?
|
182
|
+
false
|
519
183
|
end
|
520
184
|
end
|
521
185
|
end
|