concurrent-ruby 1.0.5 → 1.1.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 +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
|