o-concurrent-ruby 1.1.11

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 (142) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +542 -0
  3. data/Gemfile +37 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.md +404 -0
  6. data/Rakefile +307 -0
  7. data/ext/concurrent-ruby/ConcurrentRubyService.java +17 -0
  8. data/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java +175 -0
  9. data/ext/concurrent-ruby/com/concurrent_ruby/ext/JRubyMapBackendLibrary.java +248 -0
  10. data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicBooleanLibrary.java +93 -0
  11. data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java +113 -0
  12. data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java +189 -0
  13. data/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java +307 -0
  14. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMap.java +31 -0
  15. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java +3863 -0
  16. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/LongAdder.java +203 -0
  17. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java +342 -0
  18. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/ConcurrentHashMapV8.java +3800 -0
  19. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/LongAdder.java +204 -0
  20. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/Striped64.java +291 -0
  21. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166y/ThreadLocalRandom.java +199 -0
  22. data/lib/concurrent-ruby/concurrent/agent.rb +587 -0
  23. data/lib/concurrent-ruby/concurrent/array.rb +66 -0
  24. data/lib/concurrent-ruby/concurrent/async.rb +449 -0
  25. data/lib/concurrent-ruby/concurrent/atom.rb +222 -0
  26. data/lib/concurrent-ruby/concurrent/atomic/abstract_thread_local_var.rb +66 -0
  27. data/lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb +126 -0
  28. data/lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb +143 -0
  29. data/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb +164 -0
  30. data/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb +205 -0
  31. data/lib/concurrent-ruby/concurrent/atomic/count_down_latch.rb +100 -0
  32. data/lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb +128 -0
  33. data/lib/concurrent-ruby/concurrent/atomic/event.rb +109 -0
  34. data/lib/concurrent-ruby/concurrent/atomic/java_count_down_latch.rb +42 -0
  35. data/lib/concurrent-ruby/concurrent/atomic/java_thread_local_var.rb +37 -0
  36. data/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_boolean.rb +62 -0
  37. data/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_fixnum.rb +75 -0
  38. data/lib/concurrent-ruby/concurrent/atomic/mutex_count_down_latch.rb +44 -0
  39. data/lib/concurrent-ruby/concurrent/atomic/mutex_semaphore.rb +131 -0
  40. data/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb +254 -0
  41. data/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb +377 -0
  42. data/lib/concurrent-ruby/concurrent/atomic/ruby_thread_local_var.rb +181 -0
  43. data/lib/concurrent-ruby/concurrent/atomic/semaphore.rb +166 -0
  44. data/lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb +104 -0
  45. data/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb +56 -0
  46. data/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb +28 -0
  47. data/lib/concurrent-ruby/concurrent/atomics.rb +10 -0
  48. data/lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb +107 -0
  49. data/lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb +111 -0
  50. data/lib/concurrent-ruby/concurrent/collection/java_non_concurrent_priority_queue.rb +84 -0
  51. data/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb +158 -0
  52. data/lib/concurrent-ruby/concurrent/collection/map/atomic_reference_map_backend.rb +927 -0
  53. data/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb +66 -0
  54. data/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb +140 -0
  55. data/lib/concurrent-ruby/concurrent/collection/map/synchronized_map_backend.rb +82 -0
  56. data/lib/concurrent-ruby/concurrent/collection/map/truffleruby_map_backend.rb +14 -0
  57. data/lib/concurrent-ruby/concurrent/collection/non_concurrent_priority_queue.rb +143 -0
  58. data/lib/concurrent-ruby/concurrent/collection/ruby_non_concurrent_priority_queue.rb +160 -0
  59. data/lib/concurrent-ruby/concurrent/concern/deprecation.rb +34 -0
  60. data/lib/concurrent-ruby/concurrent/concern/dereferenceable.rb +73 -0
  61. data/lib/concurrent-ruby/concurrent/concern/logging.rb +32 -0
  62. data/lib/concurrent-ruby/concurrent/concern/obligation.rb +220 -0
  63. data/lib/concurrent-ruby/concurrent/concern/observable.rb +110 -0
  64. data/lib/concurrent-ruby/concurrent/configuration.rb +188 -0
  65. data/lib/concurrent-ruby/concurrent/constants.rb +8 -0
  66. data/lib/concurrent-ruby/concurrent/dataflow.rb +81 -0
  67. data/lib/concurrent-ruby/concurrent/delay.rb +199 -0
  68. data/lib/concurrent-ruby/concurrent/errors.rb +69 -0
  69. data/lib/concurrent-ruby/concurrent/exchanger.rb +352 -0
  70. data/lib/concurrent-ruby/concurrent/executor/abstract_executor_service.rb +131 -0
  71. data/lib/concurrent-ruby/concurrent/executor/cached_thread_pool.rb +62 -0
  72. data/lib/concurrent-ruby/concurrent/executor/executor_service.rb +185 -0
  73. data/lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb +220 -0
  74. data/lib/concurrent-ruby/concurrent/executor/immediate_executor.rb +66 -0
  75. data/lib/concurrent-ruby/concurrent/executor/indirect_immediate_executor.rb +44 -0
  76. data/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb +103 -0
  77. data/lib/concurrent-ruby/concurrent/executor/java_single_thread_executor.rb +30 -0
  78. data/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb +140 -0
  79. data/lib/concurrent-ruby/concurrent/executor/ruby_executor_service.rb +82 -0
  80. data/lib/concurrent-ruby/concurrent/executor/ruby_single_thread_executor.rb +21 -0
  81. data/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb +368 -0
  82. data/lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb +35 -0
  83. data/lib/concurrent-ruby/concurrent/executor/serial_executor_service.rb +34 -0
  84. data/lib/concurrent-ruby/concurrent/executor/serialized_execution.rb +107 -0
  85. data/lib/concurrent-ruby/concurrent/executor/serialized_execution_delegator.rb +28 -0
  86. data/lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb +100 -0
  87. data/lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb +57 -0
  88. data/lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb +88 -0
  89. data/lib/concurrent-ruby/concurrent/executor/timer_set.rb +172 -0
  90. data/lib/concurrent-ruby/concurrent/executors.rb +20 -0
  91. data/lib/concurrent-ruby/concurrent/future.rb +141 -0
  92. data/lib/concurrent-ruby/concurrent/hash.rb +59 -0
  93. data/lib/concurrent-ruby/concurrent/immutable_struct.rb +101 -0
  94. data/lib/concurrent-ruby/concurrent/ivar.rb +207 -0
  95. data/lib/concurrent-ruby/concurrent/map.rb +346 -0
  96. data/lib/concurrent-ruby/concurrent/maybe.rb +229 -0
  97. data/lib/concurrent-ruby/concurrent/mutable_struct.rb +239 -0
  98. data/lib/concurrent-ruby/concurrent/mvar.rb +242 -0
  99. data/lib/concurrent-ruby/concurrent/options.rb +42 -0
  100. data/lib/concurrent-ruby/concurrent/promise.rb +580 -0
  101. data/lib/concurrent-ruby/concurrent/promises.rb +2167 -0
  102. data/lib/concurrent-ruby/concurrent/re_include.rb +58 -0
  103. data/lib/concurrent-ruby/concurrent/scheduled_task.rb +331 -0
  104. data/lib/concurrent-ruby/concurrent/set.rb +74 -0
  105. data/lib/concurrent-ruby/concurrent/settable_struct.rb +139 -0
  106. data/lib/concurrent-ruby/concurrent/synchronization/abstract_lockable_object.rb +98 -0
  107. data/lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb +24 -0
  108. data/lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb +171 -0
  109. data/lib/concurrent-ruby/concurrent/synchronization/condition.rb +60 -0
  110. data/lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb +13 -0
  111. data/lib/concurrent-ruby/concurrent/synchronization/jruby_object.rb +45 -0
  112. data/lib/concurrent-ruby/concurrent/synchronization/lock.rb +36 -0
  113. data/lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb +72 -0
  114. data/lib/concurrent-ruby/concurrent/synchronization/mri_object.rb +44 -0
  115. data/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb +88 -0
  116. data/lib/concurrent-ruby/concurrent/synchronization/object.rb +183 -0
  117. data/lib/concurrent-ruby/concurrent/synchronization/rbx_lockable_object.rb +71 -0
  118. data/lib/concurrent-ruby/concurrent/synchronization/rbx_object.rb +49 -0
  119. data/lib/concurrent-ruby/concurrent/synchronization/truffleruby_object.rb +47 -0
  120. data/lib/concurrent-ruby/concurrent/synchronization/volatile.rb +36 -0
  121. data/lib/concurrent-ruby/concurrent/synchronization.rb +30 -0
  122. data/lib/concurrent-ruby/concurrent/thread_safe/synchronized_delegator.rb +50 -0
  123. data/lib/concurrent-ruby/concurrent/thread_safe/util/adder.rb +74 -0
  124. data/lib/concurrent-ruby/concurrent/thread_safe/util/cheap_lockable.rb +118 -0
  125. data/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb +88 -0
  126. data/lib/concurrent-ruby/concurrent/thread_safe/util/power_of_two_tuple.rb +38 -0
  127. data/lib/concurrent-ruby/concurrent/thread_safe/util/striped64.rb +246 -0
  128. data/lib/concurrent-ruby/concurrent/thread_safe/util/volatile.rb +75 -0
  129. data/lib/concurrent-ruby/concurrent/thread_safe/util/xor_shift_random.rb +50 -0
  130. data/lib/concurrent-ruby/concurrent/thread_safe/util.rb +16 -0
  131. data/lib/concurrent-ruby/concurrent/timer_task.rb +311 -0
  132. data/lib/concurrent-ruby/concurrent/tuple.rb +86 -0
  133. data/lib/concurrent-ruby/concurrent/tvar.rb +221 -0
  134. data/lib/concurrent-ruby/concurrent/utility/engine.rb +56 -0
  135. data/lib/concurrent-ruby/concurrent/utility/monotonic_time.rb +90 -0
  136. data/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb +79 -0
  137. data/lib/concurrent-ruby/concurrent/utility/native_integer.rb +53 -0
  138. data/lib/concurrent-ruby/concurrent/utility/processor_counter.rb +130 -0
  139. data/lib/concurrent-ruby/concurrent/version.rb +3 -0
  140. data/lib/concurrent-ruby/concurrent-ruby.rb +5 -0
  141. data/lib/concurrent-ruby/concurrent.rb +134 -0
  142. metadata +192 -0
@@ -0,0 +1,44 @@
1
+ require 'concurrent/executor/immediate_executor'
2
+ require 'concurrent/executor/simple_executor_service'
3
+
4
+ module Concurrent
5
+ # An executor service which runs all operations on a new thread, blocking
6
+ # until it completes. Operations are performed in the order they are received
7
+ # and no two operations can be performed simultaneously.
8
+ #
9
+ # This executor service exists mainly for testing an debugging. When used it
10
+ # immediately runs every `#post` operation on a new thread, blocking the
11
+ # current thread until the operation is complete. This is similar to how the
12
+ # ImmediateExecutor works, but the operation has the full stack of the new
13
+ # thread at its disposal. This can be helpful when the operations will spawn
14
+ # more operations on the same executor and so on - such a situation might
15
+ # overflow the single stack in case of an ImmediateExecutor, which is
16
+ # inconsistent with how it would behave for a threaded executor.
17
+ #
18
+ # @note Intended for use primarily in testing and debugging.
19
+ class IndirectImmediateExecutor < ImmediateExecutor
20
+ # Creates a new executor
21
+ def initialize
22
+ super
23
+ @internal_executor = SimpleExecutorService.new
24
+ end
25
+
26
+ # @!macro executor_service_method_post
27
+ def post(*args, &task)
28
+ raise ArgumentError.new("no block given") unless block_given?
29
+ return false unless running?
30
+
31
+ event = Concurrent::Event.new
32
+ @internal_executor.post do
33
+ begin
34
+ task.call(*args)
35
+ ensure
36
+ event.set
37
+ end
38
+ end
39
+ event.wait
40
+
41
+ true
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,103 @@
1
+ if Concurrent.on_jruby?
2
+
3
+ require 'concurrent/errors'
4
+ require 'concurrent/utility/engine'
5
+ require 'concurrent/executor/abstract_executor_service'
6
+
7
+ module Concurrent
8
+
9
+ # @!macro abstract_executor_service_public_api
10
+ # @!visibility private
11
+ class JavaExecutorService < AbstractExecutorService
12
+ java_import 'java.lang.Runnable'
13
+
14
+ FALLBACK_POLICY_CLASSES = {
15
+ abort: java.util.concurrent.ThreadPoolExecutor::AbortPolicy,
16
+ discard: java.util.concurrent.ThreadPoolExecutor::DiscardPolicy,
17
+ caller_runs: java.util.concurrent.ThreadPoolExecutor::CallerRunsPolicy
18
+ }.freeze
19
+ private_constant :FALLBACK_POLICY_CLASSES
20
+
21
+ def post(*args, &task)
22
+ raise ArgumentError.new('no block given') unless block_given?
23
+ return fallback_action(*args, &task).call unless running?
24
+ @executor.submit Job.new(args, task)
25
+ true
26
+ rescue Java::JavaUtilConcurrent::RejectedExecutionException
27
+ raise RejectedExecutionError
28
+ end
29
+
30
+ def wait_for_termination(timeout = nil)
31
+ if timeout.nil?
32
+ ok = @executor.awaitTermination(60, java.util.concurrent.TimeUnit::SECONDS) until ok
33
+ true
34
+ else
35
+ @executor.awaitTermination(1000 * timeout, java.util.concurrent.TimeUnit::MILLISECONDS)
36
+ end
37
+ end
38
+
39
+ def shutdown
40
+ synchronize do
41
+ @executor.shutdown
42
+ nil
43
+ end
44
+ end
45
+
46
+ def kill
47
+ synchronize do
48
+ @executor.shutdownNow
49
+ nil
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def ns_running?
56
+ !(ns_shuttingdown? || ns_shutdown?)
57
+ end
58
+
59
+ def ns_shuttingdown?
60
+ if @executor.respond_to? :isTerminating
61
+ @executor.isTerminating
62
+ else
63
+ false
64
+ end
65
+ end
66
+
67
+ def ns_shutdown?
68
+ @executor.isShutdown || @executor.isTerminated
69
+ end
70
+
71
+ class Job
72
+ include Runnable
73
+ def initialize(args, block)
74
+ @args = args
75
+ @block = block
76
+ end
77
+
78
+ def run
79
+ @block.call(*@args)
80
+ end
81
+ end
82
+ private_constant :Job
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
+
102
+ end
103
+ end
@@ -0,0 +1,30 @@
1
+ if Concurrent.on_jruby?
2
+
3
+ require 'concurrent/executor/java_executor_service'
4
+ require 'concurrent/executor/serial_executor_service'
5
+
6
+ module Concurrent
7
+
8
+ # @!macro single_thread_executor
9
+ # @!macro abstract_executor_service_public_api
10
+ # @!visibility private
11
+ class JavaSingleThreadExecutor < JavaExecutorService
12
+ include SerialExecutorService
13
+
14
+ # @!macro single_thread_executor_method_initialize
15
+ def initialize(opts = {})
16
+ super(opts)
17
+ end
18
+
19
+ private
20
+
21
+ def ns_initialize(opts)
22
+ @executor = java.util.concurrent.Executors.newSingleThreadExecutor(
23
+ DaemonThreadFactory.new(ns_auto_terminate?)
24
+ )
25
+ @fallback_policy = opts.fetch(:fallback_policy, :discard)
26
+ raise ArgumentError.new("#{@fallback_policy} is not a valid fallback policy") unless FALLBACK_POLICY_CLASSES.keys.include?(@fallback_policy)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,140 @@
1
+ if Concurrent.on_jruby?
2
+
3
+ require 'concurrent/executor/java_executor_service'
4
+
5
+ module Concurrent
6
+
7
+ # @!macro thread_pool_executor
8
+ # @!macro thread_pool_options
9
+ # @!visibility private
10
+ class JavaThreadPoolExecutor < JavaExecutorService
11
+
12
+ # @!macro thread_pool_executor_constant_default_max_pool_size
13
+ DEFAULT_MAX_POOL_SIZE = java.lang.Integer::MAX_VALUE # 2147483647
14
+
15
+ # @!macro thread_pool_executor_constant_default_min_pool_size
16
+ DEFAULT_MIN_POOL_SIZE = 0
17
+
18
+ # @!macro thread_pool_executor_constant_default_max_queue_size
19
+ DEFAULT_MAX_QUEUE_SIZE = 0
20
+
21
+ # @!macro thread_pool_executor_constant_default_thread_timeout
22
+ DEFAULT_THREAD_IDLETIMEOUT = 60
23
+
24
+ # @!macro thread_pool_executor_constant_default_synchronous
25
+ DEFAULT_SYNCHRONOUS = false
26
+
27
+ # @!macro thread_pool_executor_attr_reader_max_length
28
+ attr_reader :max_length
29
+
30
+ # @!macro thread_pool_executor_attr_reader_max_queue
31
+ attr_reader :max_queue
32
+
33
+ # @!macro thread_pool_executor_attr_reader_synchronous
34
+ attr_reader :synchronous
35
+
36
+ # @!macro thread_pool_executor_method_initialize
37
+ def initialize(opts = {})
38
+ super(opts)
39
+ end
40
+
41
+ # @!macro executor_service_method_can_overflow_question
42
+ def can_overflow?
43
+ @max_queue != 0
44
+ end
45
+
46
+ # @!macro thread_pool_executor_attr_reader_min_length
47
+ def min_length
48
+ @executor.getCorePoolSize
49
+ end
50
+
51
+ # @!macro thread_pool_executor_attr_reader_max_length
52
+ def max_length
53
+ @executor.getMaximumPoolSize
54
+ end
55
+
56
+ # @!macro thread_pool_executor_attr_reader_length
57
+ def length
58
+ @executor.getPoolSize
59
+ end
60
+
61
+ # @!macro thread_pool_executor_attr_reader_largest_length
62
+ def largest_length
63
+ @executor.getLargestPoolSize
64
+ end
65
+
66
+ # @!macro thread_pool_executor_attr_reader_scheduled_task_count
67
+ def scheduled_task_count
68
+ @executor.getTaskCount
69
+ end
70
+
71
+ # @!macro thread_pool_executor_attr_reader_completed_task_count
72
+ def completed_task_count
73
+ @executor.getCompletedTaskCount
74
+ end
75
+
76
+ # @!macro thread_pool_executor_attr_reader_idletime
77
+ def idletime
78
+ @executor.getKeepAliveTime(java.util.concurrent.TimeUnit::SECONDS)
79
+ end
80
+
81
+ # @!macro thread_pool_executor_attr_reader_queue_length
82
+ def queue_length
83
+ @executor.getQueue.size
84
+ end
85
+
86
+ # @!macro thread_pool_executor_attr_reader_remaining_capacity
87
+ def remaining_capacity
88
+ @max_queue == 0 ? -1 : @executor.getQueue.remainingCapacity
89
+ end
90
+
91
+ # @!macro executor_service_method_running_question
92
+ def running?
93
+ super && !@executor.isTerminating
94
+ end
95
+
96
+ # @!macro thread_pool_executor_method_prune_pool
97
+ def prune_pool
98
+ end
99
+
100
+ private
101
+
102
+ def ns_initialize(opts)
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)
108
+ @fallback_policy = opts.fetch(:fallback_policy, :abort)
109
+
110
+ raise ArgumentError.new("`synchronous` cannot be set unless `max_queue` is 0") if @synchronous && @max_queue > 0
111
+ raise ArgumentError.new("`max_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if max_length < DEFAULT_MIN_POOL_SIZE
112
+ raise ArgumentError.new("`max_threads` cannot be greater than #{DEFAULT_MAX_POOL_SIZE}") if max_length > DEFAULT_MAX_POOL_SIZE
113
+ raise ArgumentError.new("`min_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if min_length < DEFAULT_MIN_POOL_SIZE
114
+ raise ArgumentError.new("`min_threads` cannot be more than `max_threads`") if min_length > max_length
115
+ raise ArgumentError.new("#{fallback_policy} is not a valid fallback policy") unless FALLBACK_POLICY_CLASSES.include?(@fallback_policy)
116
+
117
+ if @max_queue == 0
118
+ if @synchronous
119
+ queue = java.util.concurrent.SynchronousQueue.new
120
+ else
121
+ queue = java.util.concurrent.LinkedBlockingQueue.new
122
+ end
123
+ else
124
+ queue = java.util.concurrent.LinkedBlockingQueue.new(@max_queue)
125
+ end
126
+
127
+ @executor = java.util.concurrent.ThreadPoolExecutor.new(
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)
135
+
136
+ end
137
+ end
138
+
139
+ end
140
+ end
@@ -0,0 +1,82 @@
1
+ require 'concurrent/executor/abstract_executor_service'
2
+ require 'concurrent/atomic/event'
3
+
4
+ module Concurrent
5
+
6
+ # @!macro abstract_executor_service_public_api
7
+ # @!visibility private
8
+ class RubyExecutorService < AbstractExecutorService
9
+ safe_initialization!
10
+
11
+ def initialize(*args, &block)
12
+ super
13
+ @StopEvent = Event.new
14
+ @StoppedEvent = Event.new
15
+ end
16
+
17
+ def post(*args, &task)
18
+ raise ArgumentError.new('no block given') unless block_given?
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
29
+ true
30
+ end
31
+ end
32
+
33
+ def shutdown
34
+ synchronize do
35
+ break unless running?
36
+ stop_event.set
37
+ ns_shutdown_execution
38
+ end
39
+ true
40
+ end
41
+
42
+ def kill
43
+ synchronize do
44
+ break if shutdown?
45
+ stop_event.set
46
+ ns_kill_execution
47
+ stopped_event.set
48
+ end
49
+ true
50
+ end
51
+
52
+ def wait_for_termination(timeout = nil)
53
+ stopped_event.wait(timeout)
54
+ end
55
+
56
+ private
57
+
58
+ def stop_event
59
+ @StopEvent
60
+ end
61
+
62
+ def stopped_event
63
+ @StoppedEvent
64
+ end
65
+
66
+ def ns_shutdown_execution
67
+ stopped_event.set
68
+ end
69
+
70
+ def ns_running?
71
+ !stop_event.set?
72
+ end
73
+
74
+ def ns_shuttingdown?
75
+ !(ns_running? || ns_shutdown?)
76
+ end
77
+
78
+ def ns_shutdown?
79
+ stopped_event.set?
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,21 @@
1
+ require 'concurrent/executor/ruby_thread_pool_executor'
2
+
3
+ module Concurrent
4
+
5
+ # @!macro single_thread_executor
6
+ # @!macro abstract_executor_service_public_api
7
+ # @!visibility private
8
+ class RubySingleThreadExecutor < RubyThreadPoolExecutor
9
+
10
+ # @!macro single_thread_executor_method_initialize
11
+ def initialize(opts = {})
12
+ super(
13
+ min_threads: 1,
14
+ max_threads: 1,
15
+ max_queue: 0,
16
+ idletime: DEFAULT_THREAD_IDLETIMEOUT,
17
+ fallback_policy: opts.fetch(:fallback_policy, :discard),
18
+ )
19
+ end
20
+ end
21
+ end