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
data/lib/{concurrent → concurrent-ruby/concurrent}/collection/non_concurrent_priority_queue.rb
RENAMED
@@ -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
|
@@ -15,7 +15,7 @@ module Concurrent
|
|
15
15
|
end
|
16
16
|
private_constant :NonConcurrentPriorityQueueImplementation
|
17
17
|
|
18
|
-
# @!macro
|
18
|
+
# @!macro priority_queue
|
19
19
|
#
|
20
20
|
# A queue collection in which the elements are sorted based on their
|
21
21
|
# comparison (spaceship) operator `<=>`. Items are added to the queue
|
@@ -45,7 +45,7 @@ module Concurrent
|
|
45
45
|
# @see http://algs4.cs.princeton.edu/24pq/MaxPQ.java.html
|
46
46
|
#
|
47
47
|
# @see http://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html
|
48
|
-
#
|
48
|
+
#
|
49
49
|
# @!visibility private
|
50
50
|
class NonConcurrentPriorityQueue < NonConcurrentPriorityQueueImplementation
|
51
51
|
|
@@ -60,83 +60,83 @@ module Concurrent
|
|
60
60
|
alias_method :enq, :push
|
61
61
|
|
62
62
|
# @!method initialize(opts = {})
|
63
|
-
# @!macro
|
63
|
+
# @!macro priority_queue_method_initialize
|
64
64
|
#
|
65
65
|
# Create a new priority queue with no items.
|
66
|
-
#
|
66
|
+
#
|
67
67
|
# @param [Hash] opts the options for creating the queue
|
68
68
|
# @option opts [Symbol] :order (:max) dictates the order in which items are
|
69
69
|
# stored: from highest to lowest when `:max` or `:high`; from lowest to
|
70
70
|
# highest when `:min` or `:low`
|
71
71
|
|
72
72
|
# @!method clear
|
73
|
-
# @!macro
|
73
|
+
# @!macro priority_queue_method_clear
|
74
74
|
#
|
75
75
|
# Removes all of the elements from this priority queue.
|
76
76
|
|
77
77
|
# @!method delete(item)
|
78
|
-
# @!macro
|
78
|
+
# @!macro priority_queue_method_delete
|
79
79
|
#
|
80
80
|
# Deletes all items from `self` that are equal to `item`.
|
81
|
-
#
|
81
|
+
#
|
82
82
|
# @param [Object] item the item to be removed from the queue
|
83
83
|
# @return [Object] true if the item is found else false
|
84
84
|
|
85
85
|
# @!method empty?
|
86
|
-
# @!macro
|
87
|
-
#
|
86
|
+
# @!macro priority_queue_method_empty
|
87
|
+
#
|
88
88
|
# Returns `true` if `self` contains no elements.
|
89
|
-
#
|
89
|
+
#
|
90
90
|
# @return [Boolean] true if there are no items in the queue else false
|
91
91
|
|
92
92
|
# @!method include?(item)
|
93
|
-
# @!macro
|
93
|
+
# @!macro priority_queue_method_include
|
94
94
|
#
|
95
95
|
# Returns `true` if the given item is present in `self` (that is, if any
|
96
96
|
# element == `item`), otherwise returns false.
|
97
|
-
#
|
97
|
+
#
|
98
98
|
# @param [Object] item the item to search for
|
99
|
-
#
|
99
|
+
#
|
100
100
|
# @return [Boolean] true if the item is found else false
|
101
101
|
|
102
102
|
# @!method length
|
103
|
-
# @!macro
|
104
|
-
#
|
103
|
+
# @!macro priority_queue_method_length
|
104
|
+
#
|
105
105
|
# The current length of the queue.
|
106
|
-
#
|
106
|
+
#
|
107
107
|
# @return [Fixnum] the number of items in the queue
|
108
108
|
|
109
109
|
# @!method peek
|
110
|
-
# @!macro
|
111
|
-
#
|
110
|
+
# @!macro priority_queue_method_peek
|
111
|
+
#
|
112
112
|
# Retrieves, but does not remove, the head of this queue, or returns `nil`
|
113
113
|
# if this queue is empty.
|
114
|
-
#
|
114
|
+
#
|
115
115
|
# @return [Object] the head of the queue or `nil` when empty
|
116
116
|
|
117
117
|
# @!method pop
|
118
|
-
# @!macro
|
119
|
-
#
|
118
|
+
# @!macro priority_queue_method_pop
|
119
|
+
#
|
120
120
|
# Retrieves and removes the head of this queue, or returns `nil` if this
|
121
121
|
# queue is empty.
|
122
|
-
#
|
122
|
+
#
|
123
123
|
# @return [Object] the head of the queue or `nil` when empty
|
124
124
|
|
125
125
|
# @!method push(item)
|
126
|
-
# @!macro
|
127
|
-
#
|
126
|
+
# @!macro priority_queue_method_push
|
127
|
+
#
|
128
128
|
# Inserts the specified element into this priority queue.
|
129
|
-
#
|
129
|
+
#
|
130
130
|
# @param [Object] item the item to insert onto the queue
|
131
131
|
|
132
132
|
# @!method self.from_list(list, opts = {})
|
133
|
-
# @!macro
|
134
|
-
#
|
133
|
+
# @!macro priority_queue_method_from_list
|
134
|
+
#
|
135
135
|
# Create a new priority queue from the given list.
|
136
|
-
#
|
136
|
+
#
|
137
137
|
# @param [Enumerable] list the list to build the queue from
|
138
138
|
# @param [Hash] opts the options for creating the queue
|
139
|
-
#
|
139
|
+
#
|
140
140
|
# @return [NonConcurrentPriorityQueue] the newly created and populated queue
|
141
141
|
end
|
142
142
|
end
|
data/lib/{concurrent → concurrent-ruby/concurrent}/collection/ruby_non_concurrent_priority_queue.rb
RENAMED
@@ -30,7 +30,7 @@ module Concurrent
|
|
30
30
|
if @queue[k] == item
|
31
31
|
swap(k, @length)
|
32
32
|
@length -= 1
|
33
|
-
sink(k)
|
33
|
+
sink(k) || swim(k)
|
34
34
|
@queue.pop
|
35
35
|
else
|
36
36
|
k += 1
|
@@ -126,12 +126,17 @@ module Concurrent
|
|
126
126
|
#
|
127
127
|
# @!visibility private
|
128
128
|
def sink(k)
|
129
|
+
success = false
|
130
|
+
|
129
131
|
while (j = (2 * k)) <= @length do
|
130
132
|
j += 1 if j < @length && ! ordered?(j, j+1)
|
131
133
|
break if ordered?(k, j)
|
132
134
|
swap(k, j)
|
135
|
+
success = true
|
133
136
|
k = j
|
134
137
|
end
|
138
|
+
|
139
|
+
success
|
135
140
|
end
|
136
141
|
|
137
142
|
# Percolate up to maintain heap invariant.
|
@@ -140,10 +145,15 @@ module Concurrent
|
|
140
145
|
#
|
141
146
|
# @!visibility private
|
142
147
|
def swim(k)
|
148
|
+
success = false
|
149
|
+
|
143
150
|
while k > 1 && ! ordered?(k/2, k) do
|
144
151
|
swap(k, k/2)
|
145
152
|
k = k/2
|
153
|
+
success = true
|
146
154
|
end
|
155
|
+
|
156
|
+
success
|
147
157
|
end
|
148
158
|
end
|
149
159
|
end
|
@@ -32,13 +32,13 @@ module Concurrent
|
|
32
32
|
synchronize{ @value = value }
|
33
33
|
end
|
34
34
|
|
35
|
-
# @!macro
|
35
|
+
# @!macro dereferenceable_set_deref_options
|
36
36
|
# Set the options which define the operations #value performs before
|
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
|
-
#
|
41
|
-
#
|
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
|
@@ -17,7 +17,12 @@ module Concurrent
|
|
17
17
|
def log(level, progname, message = nil, &block)
|
18
18
|
#NOTE: Cannot require 'concurrent/configuration' above due to circular references.
|
19
19
|
# Assume that the gem has been initialized if we've gotten this far.
|
20
|
-
(@logger
|
20
|
+
logger = if defined?(@logger) && @logger
|
21
|
+
@logger
|
22
|
+
else
|
23
|
+
Concurrent.global_logger
|
24
|
+
end
|
25
|
+
logger.call level, progname, message, &block
|
21
26
|
rescue => error
|
22
27
|
$stderr.puts "`Concurrent.configuration.logger` failed to log #{[level, progname, message, block]}\n" +
|
23
28
|
"#{error.message} (#{error.class})\n#{error.backtrace.join "\n"}"
|
@@ -49,7 +49,7 @@ module Concurrent
|
|
49
49
|
# or an AtomicFixum)
|
50
50
|
module Observable
|
51
51
|
|
52
|
-
# @!macro
|
52
|
+
# @!macro observable_add_observer
|
53
53
|
#
|
54
54
|
# Adds an observer to this set. If a block is passed, the observer will be
|
55
55
|
# created by this method and no other params should be passed.
|
@@ -72,8 +72,8 @@ module Concurrent
|
|
72
72
|
self
|
73
73
|
end
|
74
74
|
|
75
|
-
# @!macro
|
76
|
-
#
|
75
|
+
# @!macro observable_delete_observer
|
76
|
+
#
|
77
77
|
# Remove `observer` as an observer on this object so that it will no
|
78
78
|
# longer receive notifications.
|
79
79
|
#
|
@@ -83,17 +83,17 @@ module Concurrent
|
|
83
83
|
observers.delete_observer(observer)
|
84
84
|
end
|
85
85
|
|
86
|
-
# @!macro
|
87
|
-
#
|
86
|
+
# @!macro observable_delete_observers
|
87
|
+
#
|
88
88
|
# Remove all observers associated with this object.
|
89
|
-
#
|
89
|
+
#
|
90
90
|
# @return [Observable] self
|
91
91
|
def delete_observers
|
92
92
|
observers.delete_observers
|
93
93
|
self
|
94
94
|
end
|
95
95
|
|
96
|
-
# @!macro
|
96
|
+
# @!macro observable_count_observers
|
97
97
|
#
|
98
98
|
# Return the number of observers associated with this object.
|
99
99
|
#
|
Binary file
|
@@ -3,12 +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
|
-
require 'concurrent/
|
8
|
+
require 'concurrent/executor/cached_thread_pool'
|
8
9
|
require 'concurrent/utility/processor_counter'
|
9
10
|
|
10
11
|
module Concurrent
|
11
12
|
extend Concern::Logging
|
13
|
+
extend Concern::Deprecation
|
12
14
|
|
13
15
|
autoload :Options, 'concurrent/options'
|
14
16
|
autoload :TimerSet, 'concurrent/executor/timer_set'
|
@@ -96,15 +98,15 @@ module Concurrent
|
|
96
98
|
end
|
97
99
|
|
98
100
|
# @!visibility private
|
99
|
-
GLOBAL_FAST_EXECUTOR = Delay.new { Concurrent.new_fast_executor
|
101
|
+
GLOBAL_FAST_EXECUTOR = Delay.new { Concurrent.new_fast_executor }
|
100
102
|
private_constant :GLOBAL_FAST_EXECUTOR
|
101
103
|
|
102
104
|
# @!visibility private
|
103
|
-
GLOBAL_IO_EXECUTOR = Delay.new { Concurrent.new_io_executor
|
105
|
+
GLOBAL_IO_EXECUTOR = Delay.new { Concurrent.new_io_executor }
|
104
106
|
private_constant :GLOBAL_IO_EXECUTOR
|
105
107
|
|
106
108
|
# @!visibility private
|
107
|
-
GLOBAL_TIMER_SET = Delay.new { TimerSet.new
|
109
|
+
GLOBAL_TIMER_SET = Delay.new { TimerSet.new }
|
108
110
|
private_constant :GLOBAL_TIMER_SET
|
109
111
|
|
110
112
|
# @!visibility private
|
@@ -114,7 +116,7 @@ module Concurrent
|
|
114
116
|
# Disables AtExit handlers including pool auto-termination handlers.
|
115
117
|
# When disabled it will be the application programmer's responsibility
|
116
118
|
# to ensure that the handlers are shutdown properly prior to application
|
117
|
-
# exit by calling
|
119
|
+
# exit by calling `AtExit.run` method.
|
118
120
|
#
|
119
121
|
# @note this option should be needed only because of `at_exit` ordering
|
120
122
|
# issues which may arise when running some of the testing frameworks.
|
@@ -124,9 +126,10 @@ module Concurrent
|
|
124
126
|
# @note This method should *never* be called
|
125
127
|
# from within a gem. It should *only* be used from within the main
|
126
128
|
# application and even then it should be used only when necessary.
|
127
|
-
# @see
|
129
|
+
# @deprecated Has no effect since it is no longer needed, see https://github.com/ruby-concurrency/concurrent-ruby/pull/841.
|
130
|
+
#
|
128
131
|
def self.disable_at_exit_handlers!
|
129
|
-
|
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."
|
130
133
|
end
|
131
134
|
|
132
135
|
# Global thread pool optimized for short, fast *operations*.
|
@@ -170,19 +173,16 @@ module Concurrent
|
|
170
173
|
auto_terminate: opts.fetch(:auto_terminate, true),
|
171
174
|
idletime: 60, # 1 minute
|
172
175
|
max_queue: 0, # unlimited
|
173
|
-
fallback_policy: :abort # shouldn't matter -- 0 max queue
|
176
|
+
fallback_policy: :abort, # shouldn't matter -- 0 max queue
|
177
|
+
name: "fast"
|
174
178
|
)
|
175
179
|
end
|
176
180
|
|
177
181
|
def self.new_io_executor(opts = {})
|
178
|
-
|
179
|
-
min_threads: [2, Concurrent.processor_count].max,
|
180
|
-
max_threads: ThreadPoolExecutor::DEFAULT_MAX_POOL_SIZE,
|
181
|
-
# max_threads: 1000,
|
182
|
+
CachedThreadPool.new(
|
182
183
|
auto_terminate: opts.fetch(:auto_terminate, true),
|
183
|
-
|
184
|
-
|
185
|
-
fallback_policy: :abort # shouldn't matter -- 0 max queue
|
184
|
+
fallback_policy: :abort, # shouldn't matter -- 0 max queue
|
185
|
+
name: "io"
|
186
186
|
)
|
187
187
|
end
|
188
188
|
end
|
@@ -18,7 +18,8 @@ module Concurrent
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
#
|
21
|
+
# Dataflow allows you to create a task that will be scheduled when all of its data dependencies are available.
|
22
|
+
# {include:file:docs-source/dataflow.md}
|
22
23
|
#
|
23
24
|
# @param [Future] inputs zero or more `Future` operations that this dataflow depends upon
|
24
25
|
#
|
@@ -32,7 +32,7 @@ module Concurrent
|
|
32
32
|
#
|
33
33
|
# @!macro copy_options
|
34
34
|
#
|
35
|
-
# @!macro
|
35
|
+
# @!macro delay_note_regarding_blocking
|
36
36
|
# @note The default behavior of `Delay` is to block indefinitely when
|
37
37
|
# calling either `value` or `wait`, executing the delayed operation on
|
38
38
|
# the current thread. This makes the `timeout` value completely
|
@@ -81,13 +81,15 @@ module Concurrent
|
|
81
81
|
# this function has been optimized for performance and
|
82
82
|
# should not be modified without running new benchmarks
|
83
83
|
synchronize do
|
84
|
-
execute = @
|
84
|
+
execute = @evaluation_started = true unless @evaluation_started
|
85
85
|
if execute
|
86
86
|
begin
|
87
87
|
set_state(true, @task.call, nil)
|
88
88
|
rescue => ex
|
89
89
|
set_state(false, nil, ex)
|
90
90
|
end
|
91
|
+
elsif incomplete?
|
92
|
+
raise IllegalOperationError, 'Recursive call to #value during evaluation of the Delay'
|
91
93
|
end
|
92
94
|
end
|
93
95
|
if @do_nothing_on_deref
|
@@ -144,7 +146,7 @@ module Concurrent
|
|
144
146
|
def reconfigure(&block)
|
145
147
|
synchronize do
|
146
148
|
raise ArgumentError.new('no block given') unless block_given?
|
147
|
-
unless @
|
149
|
+
unless @evaluation_started
|
148
150
|
@task = block
|
149
151
|
true
|
150
152
|
else
|
@@ -160,9 +162,9 @@ module Concurrent
|
|
160
162
|
set_deref_options(opts)
|
161
163
|
@executor = opts[:executor]
|
162
164
|
|
163
|
-
@task
|
164
|
-
@state
|
165
|
-
@
|
165
|
+
@task = block
|
166
|
+
@state = :pending
|
167
|
+
@evaluation_started = false
|
166
168
|
end
|
167
169
|
|
168
170
|
private
|
@@ -173,7 +175,7 @@ module Concurrent
|
|
173
175
|
# should not be modified without running new benchmarks
|
174
176
|
execute = task = nil
|
175
177
|
synchronize do
|
176
|
-
execute = @
|
178
|
+
execute = @evaluation_started = true unless @evaluation_started
|
177
179
|
task = @task
|
178
180
|
end
|
179
181
|
|
@@ -8,7 +8,7 @@ require 'concurrent/utility/monotonic_time'
|
|
8
8
|
|
9
9
|
module Concurrent
|
10
10
|
|
11
|
-
# @!macro
|
11
|
+
# @!macro exchanger
|
12
12
|
#
|
13
13
|
# A synchronization point at which threads can pair and swap elements within
|
14
14
|
# pairs. Each thread presents some object on entry to the exchange method,
|
@@ -24,9 +24,6 @@ module Concurrent
|
|
24
24
|
# will remain correct.
|
25
25
|
#
|
26
26
|
# @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Exchanger.html java.util.concurrent.Exchanger
|
27
|
-
#
|
28
|
-
# @!macro edge_warning
|
29
|
-
#
|
30
27
|
# @example
|
31
28
|
#
|
32
29
|
# exchanger = Concurrent::Exchanger.new
|
@@ -36,20 +33,19 @@ module Concurrent
|
|
36
33
|
# Thread.new { puts "second: " << exchanger.exchange('bar', 1) } #=> "second: foo"
|
37
34
|
# ]
|
38
35
|
# threads.each {|t| t.join(2) }
|
39
|
-
|
36
|
+
|
40
37
|
# @!visibility private
|
41
38
|
class AbstractExchanger < Synchronization::Object
|
42
39
|
|
43
40
|
# @!visibility private
|
44
|
-
CANCEL = Object.new
|
41
|
+
CANCEL = ::Object.new
|
45
42
|
private_constant :CANCEL
|
46
43
|
|
47
|
-
# @!macro [attach] exchanger_method_initialize
|
48
44
|
def initialize
|
49
45
|
super
|
50
46
|
end
|
51
47
|
|
52
|
-
# @!macro
|
48
|
+
# @!macro exchanger_method_do_exchange
|
53
49
|
#
|
54
50
|
# Waits for another thread to arrive at this exchange point (unless the
|
55
51
|
# current thread is interrupted), and then transfers the given object to
|
@@ -61,7 +57,7 @@ module Concurrent
|
|
61
57
|
# @param [Object] value the value to exchange with another thread
|
62
58
|
# @param [Numeric, nil] timeout in seconds, `nil` blocks indefinitely
|
63
59
|
#
|
64
|
-
# @!macro
|
60
|
+
# @!macro exchanger_method_exchange
|
65
61
|
#
|
66
62
|
# In some edge cases when a `timeout` is given a return value of `nil` may be
|
67
63
|
# ambiguous. Specifically, if `nil` is a valid value in the exchange it will
|
@@ -75,8 +71,7 @@ module Concurrent
|
|
75
71
|
end
|
76
72
|
|
77
73
|
# @!macro exchanger_method_do_exchange
|
78
|
-
#
|
79
|
-
# @!macro [attach] exchanger_method_exchange_bang
|
74
|
+
# @!macro exchanger_method_exchange_bang
|
80
75
|
#
|
81
76
|
# On timeout a {Concurrent::TimeoutError} exception will be raised.
|
82
77
|
#
|
@@ -91,8 +86,7 @@ module Concurrent
|
|
91
86
|
end
|
92
87
|
|
93
88
|
# @!macro exchanger_method_do_exchange
|
94
|
-
#
|
95
|
-
# @!macro [attach] exchanger_method_try_exchange
|
89
|
+
# @!macro exchanger_method_try_exchange
|
96
90
|
#
|
97
91
|
# The return value will be a {Concurrent::Maybe} set to `Just` on success or
|
98
92
|
# `Nothing` on timeout.
|
@@ -130,7 +124,6 @@ module Concurrent
|
|
130
124
|
end
|
131
125
|
end
|
132
126
|
|
133
|
-
# @!macro exchanger
|
134
127
|
# @!macro internal_implementation_note
|
135
128
|
# @!visibility private
|
136
129
|
class RubyExchanger < AbstractExchanger
|
@@ -148,8 +141,8 @@ module Concurrent
|
|
148
141
|
|
149
142
|
def initialize(item)
|
150
143
|
super()
|
151
|
-
@Item
|
152
|
-
@Latch
|
144
|
+
@Item = item
|
145
|
+
@Latch = Concurrent::CountDownLatch.new
|
153
146
|
self.value = nil
|
154
147
|
end
|
155
148
|
|
@@ -163,7 +156,6 @@ module Concurrent
|
|
163
156
|
end
|
164
157
|
private_constant :Node
|
165
158
|
|
166
|
-
# @!macro exchanger_method_initialize
|
167
159
|
def initialize
|
168
160
|
super
|
169
161
|
end
|
@@ -218,7 +210,7 @@ module Concurrent
|
|
218
210
|
# node's initial value. It never changes. It's what the fulfiller returns on
|
219
211
|
# success. The occupier's hole is where the fulfiller put its item. It's the
|
220
212
|
# item that the occupier returns on success. The latch is used for synchronization.
|
221
|
-
#
|
213
|
+
# Because a thread may act as either an occupier or fulfiller (or possibly
|
222
214
|
# both in periods of high contention) every thread creates a node when
|
223
215
|
# the exchange method is first called.
|
224
216
|
#
|
@@ -260,8 +252,8 @@ module Concurrent
|
|
260
252
|
# - Wake the sleeping occupier
|
261
253
|
# - Return the occupier's item
|
262
254
|
|
263
|
-
value
|
264
|
-
me
|
255
|
+
value = NULL if value.nil? # The sentinel allows nil to be a valid value
|
256
|
+
me = Node.new(value) # create my node in case I need to occupy
|
265
257
|
end_at = Concurrent.monotonic_time + timeout.to_f # The time to give up
|
266
258
|
|
267
259
|
result = loop do
|
@@ -298,12 +290,10 @@ module Concurrent
|
|
298
290
|
|
299
291
|
if Concurrent.on_jruby?
|
300
292
|
|
301
|
-
# @!macro exchanger
|
302
293
|
# @!macro internal_implementation_note
|
303
294
|
# @!visibility private
|
304
295
|
class JavaExchanger < AbstractExchanger
|
305
296
|
|
306
|
-
# @!macro exchanger_method_initialize
|
307
297
|
def initialize
|
308
298
|
@exchanger = java.util.concurrent.Exchanger.new
|
309
299
|
end
|
@@ -314,11 +304,17 @@ module Concurrent
|
|
314
304
|
#
|
315
305
|
# @return [Object, CANCEL] the value exchanged by the other thread; {CANCEL} on timeout
|
316
306
|
def do_exchange(value, timeout)
|
307
|
+
result = nil
|
317
308
|
if timeout.nil?
|
318
|
-
|
309
|
+
Synchronization::JRuby.sleep_interruptibly do
|
310
|
+
result = @exchanger.exchange(value)
|
311
|
+
end
|
319
312
|
else
|
320
|
-
|
313
|
+
Synchronization::JRuby.sleep_interruptibly do
|
314
|
+
result = @exchanger.exchange(value, 1000 * timeout, java.util.concurrent.TimeUnit::MILLISECONDS)
|
315
|
+
end
|
321
316
|
end
|
317
|
+
result
|
322
318
|
rescue java.util.concurrent.TimeoutException
|
323
319
|
CANCEL
|
324
320
|
end
|
@@ -339,7 +335,7 @@ module Concurrent
|
|
339
335
|
class Exchanger < ExchangerImplementation
|
340
336
|
|
341
337
|
# @!method initialize
|
342
|
-
#
|
338
|
+
# Creates exchanger instance
|
343
339
|
|
344
340
|
# @!method exchange(value, timeout = nil)
|
345
341
|
# @!macro exchanger_method_do_exchange
|