concurrent-ruby 1.0.5 → 1.1.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +42 -0
- data/Gemfile +39 -0
- data/{LICENSE.txt → LICENSE.md} +2 -0
- data/README.md +203 -105
- data/Rakefile +278 -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 +159 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java +304 -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-ruby.rb +1 -0
- data/lib/concurrent.rb +24 -20
- data/lib/concurrent/agent.rb +7 -7
- data/lib/concurrent/array.rb +59 -32
- data/lib/concurrent/async.rb +4 -4
- data/lib/concurrent/atom.rb +9 -9
- data/lib/concurrent/atomic/atomic_boolean.rb +24 -20
- data/lib/concurrent/atomic/atomic_fixnum.rb +27 -23
- data/lib/concurrent/atomic/atomic_markable_reference.rb +164 -0
- data/lib/concurrent/atomic/atomic_reference.rb +176 -33
- data/lib/concurrent/atomic/count_down_latch.rb +6 -6
- data/lib/concurrent/atomic/cyclic_barrier.rb +1 -1
- data/lib/concurrent/atomic/event.rb +1 -1
- data/lib/concurrent/atomic/java_count_down_latch.rb +6 -5
- data/lib/concurrent/atomic/mutex_count_down_latch.rb +1 -0
- data/lib/concurrent/atomic/read_write_lock.rb +2 -1
- data/lib/concurrent/atomic/reentrant_read_write_lock.rb +3 -1
- data/lib/concurrent/atomic/semaphore.rb +8 -8
- data/lib/concurrent/atomic/thread_local_var.rb +7 -7
- data/lib/concurrent/atomic_reference/mutex_atomic.rb +3 -8
- data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +1 -1
- data/lib/concurrent/atomics.rb +0 -43
- data/lib/concurrent/collection/lock_free_stack.rb +127 -0
- data/lib/concurrent/collection/map/atomic_reference_map_backend.rb +3 -3
- data/lib/concurrent/collection/map/non_concurrent_map_backend.rb +1 -2
- data/lib/concurrent/collection/non_concurrent_priority_queue.rb +29 -29
- data/lib/concurrent/concern/dereferenceable.rb +1 -1
- data/lib/concurrent/concern/logging.rb +6 -1
- data/lib/concurrent/concern/observable.rb +7 -7
- data/lib/concurrent/concurrent_ruby.jar +0 -0
- data/lib/concurrent/configuration.rb +1 -6
- data/lib/concurrent/constants.rb +1 -1
- data/lib/concurrent/dataflow.rb +2 -1
- data/lib/concurrent/delay.rb +9 -7
- data/lib/concurrent/exchanger.rb +13 -21
- data/lib/concurrent/executor/abstract_executor_service.rb +2 -2
- data/lib/concurrent/executor/cached_thread_pool.rb +1 -1
- data/lib/concurrent/executor/executor_service.rb +15 -15
- data/lib/concurrent/executor/fixed_thread_pool.rb +18 -18
- data/lib/concurrent/executor/java_thread_pool_executor.rb +10 -7
- data/lib/concurrent/executor/single_thread_executor.rb +2 -2
- data/lib/concurrent/executor/thread_pool_executor.rb +6 -6
- data/lib/concurrent/executor/timer_set.rb +1 -1
- data/lib/concurrent/future.rb +4 -1
- data/lib/concurrent/hash.rb +53 -30
- data/lib/concurrent/ivar.rb +5 -6
- data/lib/concurrent/map.rb +20 -25
- data/lib/concurrent/maybe.rb +1 -1
- data/lib/concurrent/mutable_struct.rb +15 -14
- data/lib/concurrent/mvar.rb +2 -2
- data/lib/concurrent/promise.rb +53 -21
- data/lib/concurrent/promises.rb +1938 -0
- data/lib/concurrent/re_include.rb +58 -0
- data/lib/concurrent/set.rb +66 -0
- data/lib/concurrent/settable_struct.rb +1 -0
- data/lib/concurrent/synchronization.rb +4 -5
- data/lib/concurrent/synchronization/abstract_lockable_object.rb +5 -5
- data/lib/concurrent/synchronization/abstract_struct.rb +6 -4
- data/lib/concurrent/synchronization/lockable_object.rb +6 -6
- data/lib/concurrent/synchronization/{mri_lockable_object.rb → mutex_lockable_object.rb} +19 -14
- data/lib/concurrent/synchronization/object.rb +8 -4
- data/lib/concurrent/synchronization/truffleruby_object.rb +46 -0
- data/lib/concurrent/synchronization/volatile.rb +11 -9
- data/lib/concurrent/thread_safe/util/data_structures.rb +55 -0
- data/lib/concurrent/thread_safe/util/striped64.rb +9 -4
- data/lib/concurrent/timer_task.rb +5 -2
- data/lib/concurrent/tuple.rb +1 -1
- data/lib/concurrent/tvar.rb +2 -2
- data/lib/concurrent/utility/at_exit.rb +1 -1
- data/lib/concurrent/utility/engine.rb +2 -2
- data/lib/concurrent/utility/monotonic_time.rb +3 -3
- data/lib/concurrent/utility/native_extension_loader.rb +31 -33
- data/lib/concurrent/utility/processor_counter.rb +0 -2
- data/lib/concurrent/version.rb +2 -2
- metadata +35 -21
- 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/edge.rb +0 -26
- data/lib/concurrent/lazy_register.rb +0 -81
- 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
@@ -1,16 +1,11 @@
|
|
1
|
-
require 'concurrent/synchronization'
|
2
|
-
require 'concurrent/atomic_reference/direct_update'
|
3
|
-
require 'concurrent/atomic_reference/numeric_cas_wrapper'
|
4
|
-
|
5
1
|
module Concurrent
|
6
2
|
|
7
|
-
# @!macro atomic_reference
|
8
|
-
#
|
9
3
|
# @!visibility private
|
10
4
|
# @!macro internal_implementation_note
|
11
5
|
class MutexAtomicReference < Synchronization::LockableObject
|
12
|
-
include
|
13
|
-
include
|
6
|
+
include AtomicDirectUpdate
|
7
|
+
include AtomicNumericCompareAndSetWrapper
|
8
|
+
alias_method :compare_and_swap, :compare_and_set
|
14
9
|
|
15
10
|
# @!macro atomic_reference_method_initialize
|
16
11
|
def initialize(value = nil)
|
data/lib/concurrent/atomics.rb
CHANGED
@@ -1,46 +1,3 @@
|
|
1
|
-
# @!macro [new] atomic_reference
|
2
|
-
#
|
3
|
-
# An object reference that may be updated atomically. All read and write
|
4
|
-
# operations have java volatile semantic.
|
5
|
-
#
|
6
|
-
# @!macro thread_safe_variable_comparison
|
7
|
-
#
|
8
|
-
# @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicReference.html
|
9
|
-
# @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/package-summary.html
|
10
|
-
#
|
11
|
-
# @!method initialize
|
12
|
-
# @!macro [new] atomic_reference_method_initialize
|
13
|
-
# @param [Object] value The initial value.
|
14
|
-
#
|
15
|
-
# @!method get
|
16
|
-
# @!macro [new] atomic_reference_method_get
|
17
|
-
# Gets the current value.
|
18
|
-
# @return [Object] the current value
|
19
|
-
#
|
20
|
-
# @!method set
|
21
|
-
# @!macro [new] atomic_reference_method_set
|
22
|
-
# Sets to the given value.
|
23
|
-
# @param [Object] new_value the new value
|
24
|
-
# @return [Object] the new value
|
25
|
-
#
|
26
|
-
# @!method get_and_set
|
27
|
-
# @!macro [new] atomic_reference_method_get_and_set
|
28
|
-
# Atomically sets to the given value and returns the old value.
|
29
|
-
# @param [Object] new_value the new value
|
30
|
-
# @return [Object] the old value
|
31
|
-
#
|
32
|
-
# @!method compare_and_set
|
33
|
-
# @!macro [new] atomic_reference_method_compare_and_set
|
34
|
-
#
|
35
|
-
# Atomically sets the value to the given updated value if
|
36
|
-
# the current value == the expected value.
|
37
|
-
#
|
38
|
-
# @param [Object] old_value the expected value
|
39
|
-
# @param [Object] new_value the new value
|
40
|
-
#
|
41
|
-
# @return [Boolean] `true` if successful. A `false` return indicates
|
42
|
-
# that the actual value was not equal to the expected value.
|
43
|
-
|
44
1
|
require 'concurrent/atomic/atomic_reference'
|
45
2
|
require 'concurrent/atomic/atomic_boolean'
|
46
3
|
require 'concurrent/atomic/atomic_fixnum'
|
@@ -0,0 +1,127 @@
|
|
1
|
+
module Concurrent
|
2
|
+
|
3
|
+
# @!visibility private
|
4
|
+
class LockFreeStack < Synchronization::Object
|
5
|
+
|
6
|
+
safe_initialization!
|
7
|
+
|
8
|
+
class Node
|
9
|
+
# TODO (pitr-ch 20-Dec-2016): Could be unified with Stack class?
|
10
|
+
|
11
|
+
attr_reader :value, :next_node
|
12
|
+
# allow to nil-ify to free GC when the entry is no longer relevant, not synchronised
|
13
|
+
attr_writer :value
|
14
|
+
|
15
|
+
def initialize(value, next_node)
|
16
|
+
@value = value
|
17
|
+
@next_node = next_node
|
18
|
+
end
|
19
|
+
|
20
|
+
singleton_class.send :alias_method, :[], :new
|
21
|
+
end
|
22
|
+
|
23
|
+
class Empty < Node
|
24
|
+
def next_node
|
25
|
+
self
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
EMPTY = Empty[nil, nil]
|
30
|
+
|
31
|
+
attr_atomic(:head)
|
32
|
+
private :head, :head=, :swap_head, :compare_and_set_head, :update_head
|
33
|
+
|
34
|
+
def self.of1(value)
|
35
|
+
new Node[value, EMPTY]
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.of2(value1, value2)
|
39
|
+
new Node[value1, Node[value2, EMPTY]]
|
40
|
+
end
|
41
|
+
|
42
|
+
def initialize(head = EMPTY)
|
43
|
+
super()
|
44
|
+
self.head = head
|
45
|
+
end
|
46
|
+
|
47
|
+
def empty?(head = self.head)
|
48
|
+
head.equal? EMPTY
|
49
|
+
end
|
50
|
+
|
51
|
+
def compare_and_push(head, value)
|
52
|
+
compare_and_set_head head, Node[value, head]
|
53
|
+
end
|
54
|
+
|
55
|
+
def push(value)
|
56
|
+
while true
|
57
|
+
current_head = head
|
58
|
+
return self if compare_and_set_head current_head, Node[value, current_head]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def peek
|
63
|
+
head
|
64
|
+
end
|
65
|
+
|
66
|
+
def compare_and_pop(head)
|
67
|
+
compare_and_set_head head, head.next_node
|
68
|
+
end
|
69
|
+
|
70
|
+
def pop
|
71
|
+
while true
|
72
|
+
current_head = head
|
73
|
+
return current_head.value if compare_and_set_head current_head, current_head.next_node
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def compare_and_clear(head)
|
78
|
+
compare_and_set_head head, EMPTY
|
79
|
+
end
|
80
|
+
|
81
|
+
include Enumerable
|
82
|
+
|
83
|
+
def each(head = nil)
|
84
|
+
return to_enum(:each, head) unless block_given?
|
85
|
+
it = head || peek
|
86
|
+
until it.equal?(EMPTY)
|
87
|
+
yield it.value
|
88
|
+
it = it.next_node
|
89
|
+
end
|
90
|
+
self
|
91
|
+
end
|
92
|
+
|
93
|
+
def clear
|
94
|
+
while true
|
95
|
+
current_head = head
|
96
|
+
return false if current_head == EMPTY
|
97
|
+
return true if compare_and_set_head current_head, EMPTY
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def clear_if(head)
|
102
|
+
compare_and_set_head head, EMPTY
|
103
|
+
end
|
104
|
+
|
105
|
+
def replace_if(head, new_head)
|
106
|
+
compare_and_set_head head, new_head
|
107
|
+
end
|
108
|
+
|
109
|
+
def clear_each(&block)
|
110
|
+
while true
|
111
|
+
current_head = head
|
112
|
+
return self if current_head == EMPTY
|
113
|
+
if compare_and_set_head current_head, EMPTY
|
114
|
+
each current_head, &block
|
115
|
+
return self
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# @return [String] Short string representation.
|
121
|
+
def to_s
|
122
|
+
format '%s %s>', super[0..-2], to_a.to_s
|
123
|
+
end
|
124
|
+
|
125
|
+
alias_method :inspect, :to_s
|
126
|
+
end
|
127
|
+
end
|
@@ -289,7 +289,7 @@ module Concurrent
|
|
289
289
|
end
|
290
290
|
end
|
291
291
|
elsif cas_hash(my_hash, my_hash | WAITING)
|
292
|
-
|
292
|
+
force_acquire_lock(table, i)
|
293
293
|
break
|
294
294
|
end
|
295
295
|
end
|
@@ -330,7 +330,7 @@ module Concurrent
|
|
330
330
|
end
|
331
331
|
|
332
332
|
private
|
333
|
-
def
|
333
|
+
def force_acquire_lock(table, i)
|
334
334
|
cheap_synchronize do
|
335
335
|
if equal?(table.volatile_get(i)) && (hash & WAITING) == WAITING
|
336
336
|
cheap_wait
|
@@ -831,7 +831,7 @@ module Concurrent
|
|
831
831
|
# no lock needed (or available) if bin >= 0, because we're not popping values from locked_indexes until we've run through the whole table
|
832
832
|
redo unless (bin >= 0 ? table.cas(i, nil, forwarder) : lock_and_clean_up_reverse_forwarders(table, old_table_size, new_table, i, forwarder))
|
833
833
|
elsif Node.locked_hash?(node_hash = node.hash)
|
834
|
-
locked_indexes ||= Array.new
|
834
|
+
locked_indexes ||= ::Array.new
|
835
835
|
if bin < 0 && locked_arr_idx > 0
|
836
836
|
locked_arr_idx -= 1
|
837
837
|
i, locked_indexes[locked_arr_idx] = locked_indexes[locked_arr_idx], i # swap with another bin
|
@@ -10,7 +10,7 @@ module Concurrent
|
|
10
10
|
|
11
11
|
# WARNING: all public methods of the class must operate on the @backend
|
12
12
|
# directly without calling each other. This is important because of the
|
13
|
-
# SynchronizedMapBackend which uses a non-reentrant mutex for
|
13
|
+
# SynchronizedMapBackend which uses a non-reentrant mutex for performance
|
14
14
|
# reasons.
|
15
15
|
def initialize(options = nil)
|
16
16
|
@backend = {}
|
@@ -95,7 +95,6 @@ module Concurrent
|
|
95
95
|
end
|
96
96
|
|
97
97
|
def each_pair
|
98
|
-
return enum_for :each_pair unless block_given?
|
99
98
|
dupped_backend.each_pair do |k, v|
|
100
99
|
yield k, v
|
101
100
|
end
|
@@ -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
|
@@ -32,7 +32,7 @@ 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
|
#
|
@@ -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
|
@@ -175,13 +175,8 @@ module Concurrent
|
|
175
175
|
end
|
176
176
|
|
177
177
|
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,
|
178
|
+
CachedThreadPool.new(
|
182
179
|
auto_terminate: opts.fetch(:auto_terminate, true),
|
183
|
-
idletime: 60, # 1 minute
|
184
|
-
max_queue: 0, # unlimited
|
185
180
|
fallback_policy: :abort # shouldn't matter -- 0 max queue
|
186
181
|
)
|
187
182
|
end
|