concurrent-ruby 0.8.0.pre2-java → 0.9.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +114 -3
- data/README.md +111 -55
- data/lib/concurrent.rb +90 -14
- data/lib/concurrent/async.rb +143 -51
- data/lib/concurrent/atom.rb +131 -0
- data/lib/concurrent/atomic/atomic_boolean.rb +57 -107
- data/lib/concurrent/atomic/atomic_fixnum.rb +73 -101
- data/lib/concurrent/atomic/atomic_reference.rb +49 -0
- data/lib/concurrent/atomic/condition.rb +23 -12
- data/lib/concurrent/atomic/count_down_latch.rb +23 -21
- data/lib/concurrent/atomic/cyclic_barrier.rb +47 -47
- data/lib/concurrent/atomic/event.rb +33 -42
- data/lib/concurrent/atomic/read_write_lock.rb +252 -0
- data/lib/concurrent/atomic/semaphore.rb +64 -89
- data/lib/concurrent/atomic/thread_local_var.rb +130 -58
- data/lib/concurrent/atomic/thread_local_var/weak_key_map.rb +236 -0
- data/lib/concurrent/atomic_reference/direct_update.rb +34 -3
- data/lib/concurrent/atomic_reference/jruby.rb +6 -3
- data/lib/concurrent/atomic_reference/mutex_atomic.rb +17 -39
- data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +3 -0
- data/lib/concurrent/atomic_reference/rbx.rb +4 -1
- data/lib/concurrent/atomic_reference/ruby.rb +6 -3
- data/lib/concurrent/atomics.rb +74 -4
- data/lib/concurrent/collection/copy_on_notify_observer_set.rb +115 -0
- data/lib/concurrent/collection/copy_on_write_observer_set.rb +119 -0
- data/lib/concurrent/collection/priority_queue.rb +300 -245
- data/lib/concurrent/concern/deprecation.rb +34 -0
- data/lib/concurrent/concern/dereferenceable.rb +88 -0
- data/lib/concurrent/concern/logging.rb +27 -0
- data/lib/concurrent/concern/obligation.rb +228 -0
- data/lib/concurrent/concern/observable.rb +85 -0
- data/lib/concurrent/configuration.rb +234 -109
- data/lib/concurrent/dataflow.rb +2 -3
- data/lib/concurrent/delay.rb +141 -50
- data/lib/concurrent/edge.rb +30 -0
- data/lib/concurrent/errors.rb +19 -7
- data/lib/concurrent/exchanger.rb +25 -1
- data/lib/concurrent/executor/cached_thread_pool.rb +51 -33
- data/lib/concurrent/executor/executor.rb +46 -299
- data/lib/concurrent/executor/executor_service.rb +521 -0
- data/lib/concurrent/executor/fixed_thread_pool.rb +196 -23
- data/lib/concurrent/executor/immediate_executor.rb +9 -9
- data/lib/concurrent/executor/indirect_immediate_executor.rb +4 -3
- data/lib/concurrent/executor/java_single_thread_executor.rb +17 -16
- data/lib/concurrent/executor/java_thread_pool_executor.rb +55 -102
- data/lib/concurrent/executor/ruby_single_thread_executor.rb +14 -16
- data/lib/concurrent/executor/ruby_thread_pool_executor.rb +250 -166
- data/lib/concurrent/executor/safe_task_executor.rb +5 -4
- data/lib/concurrent/executor/serialized_execution.rb +22 -18
- data/lib/concurrent/executor/{per_thread_executor.rb → simple_executor_service.rb} +29 -20
- data/lib/concurrent/executor/single_thread_executor.rb +32 -21
- data/lib/concurrent/executor/thread_pool_executor.rb +73 -60
- data/lib/concurrent/executor/timer_set.rb +96 -84
- data/lib/concurrent/executors.rb +1 -1
- data/lib/concurrent/future.rb +71 -38
- data/lib/concurrent/immutable_struct.rb +89 -0
- data/lib/concurrent/ivar.rb +152 -60
- data/lib/concurrent/lazy_register.rb +40 -20
- data/lib/concurrent/maybe.rb +226 -0
- data/lib/concurrent/mutable_struct.rb +227 -0
- data/lib/concurrent/mvar.rb +44 -43
- data/lib/concurrent/promise.rb +229 -136
- data/lib/concurrent/scheduled_task.rb +341 -43
- data/lib/concurrent/settable_struct.rb +127 -0
- data/lib/concurrent/synchronization.rb +17 -0
- data/lib/concurrent/synchronization/abstract_object.rb +163 -0
- data/lib/concurrent/synchronization/abstract_struct.rb +158 -0
- data/lib/concurrent/synchronization/condition.rb +53 -0
- data/lib/concurrent/synchronization/java_object.rb +34 -0
- data/lib/concurrent/synchronization/lock.rb +32 -0
- data/lib/concurrent/synchronization/monitor_object.rb +26 -0
- data/lib/concurrent/synchronization/mutex_object.rb +43 -0
- data/lib/concurrent/synchronization/object.rb +78 -0
- data/lib/concurrent/synchronization/rbx_object.rb +75 -0
- data/lib/concurrent/timer_task.rb +92 -103
- data/lib/concurrent/tvar.rb +42 -38
- data/lib/concurrent/utilities.rb +3 -1
- data/lib/concurrent/utility/at_exit.rb +97 -0
- data/lib/concurrent/utility/engine.rb +44 -0
- data/lib/concurrent/utility/monotonic_time.rb +59 -0
- data/lib/concurrent/utility/native_extension_loader.rb +56 -0
- data/lib/concurrent/utility/processor_counter.rb +156 -0
- data/lib/concurrent/utility/timeout.rb +18 -14
- data/lib/concurrent/utility/timer.rb +11 -6
- data/lib/concurrent/version.rb +2 -1
- data/lib/concurrent_ruby.rb +1 -0
- data/lib/concurrent_ruby_ext.jar +0 -0
- metadata +46 -66
- data/lib/concurrent/actor.rb +0 -103
- data/lib/concurrent/actor/behaviour.rb +0 -70
- data/lib/concurrent/actor/behaviour/abstract.rb +0 -48
- data/lib/concurrent/actor/behaviour/awaits.rb +0 -21
- data/lib/concurrent/actor/behaviour/buffer.rb +0 -54
- data/lib/concurrent/actor/behaviour/errors_on_unknown_message.rb +0 -12
- data/lib/concurrent/actor/behaviour/executes_context.rb +0 -18
- data/lib/concurrent/actor/behaviour/linking.rb +0 -45
- data/lib/concurrent/actor/behaviour/pausing.rb +0 -77
- data/lib/concurrent/actor/behaviour/removes_child.rb +0 -16
- data/lib/concurrent/actor/behaviour/sets_results.rb +0 -36
- data/lib/concurrent/actor/behaviour/supervised.rb +0 -59
- data/lib/concurrent/actor/behaviour/supervising.rb +0 -34
- data/lib/concurrent/actor/behaviour/terminates_children.rb +0 -13
- data/lib/concurrent/actor/behaviour/termination.rb +0 -54
- data/lib/concurrent/actor/context.rb +0 -154
- data/lib/concurrent/actor/core.rb +0 -217
- data/lib/concurrent/actor/default_dead_letter_handler.rb +0 -9
- data/lib/concurrent/actor/envelope.rb +0 -41
- data/lib/concurrent/actor/errors.rb +0 -27
- data/lib/concurrent/actor/internal_delegations.rb +0 -49
- data/lib/concurrent/actor/public_delegations.rb +0 -40
- data/lib/concurrent/actor/reference.rb +0 -81
- data/lib/concurrent/actor/root.rb +0 -37
- data/lib/concurrent/actor/type_check.rb +0 -48
- data/lib/concurrent/actor/utils.rb +0 -10
- data/lib/concurrent/actor/utils/ad_hoc.rb +0 -21
- data/lib/concurrent/actor/utils/balancer.rb +0 -42
- data/lib/concurrent/actor/utils/broadcast.rb +0 -52
- data/lib/concurrent/actor/utils/pool.rb +0 -59
- data/lib/concurrent/actress.rb +0 -3
- data/lib/concurrent/agent.rb +0 -209
- data/lib/concurrent/atomic.rb +0 -92
- data/lib/concurrent/atomic/copy_on_notify_observer_set.rb +0 -118
- data/lib/concurrent/atomic/copy_on_write_observer_set.rb +0 -117
- data/lib/concurrent/atomic/synchronization.rb +0 -51
- data/lib/concurrent/channel/buffered_channel.rb +0 -85
- data/lib/concurrent/channel/channel.rb +0 -41
- data/lib/concurrent/channel/unbuffered_channel.rb +0 -35
- data/lib/concurrent/channel/waitable_list.rb +0 -40
- data/lib/concurrent/channels.rb +0 -5
- data/lib/concurrent/collection/blocking_ring_buffer.rb +0 -71
- data/lib/concurrent/collection/ring_buffer.rb +0 -59
- data/lib/concurrent/collections.rb +0 -3
- data/lib/concurrent/dereferenceable.rb +0 -108
- data/lib/concurrent/executor/java_cached_thread_pool.rb +0 -32
- data/lib/concurrent/executor/java_fixed_thread_pool.rb +0 -31
- data/lib/concurrent/executor/ruby_cached_thread_pool.rb +0 -29
- data/lib/concurrent/executor/ruby_fixed_thread_pool.rb +0 -32
- data/lib/concurrent/executor/ruby_thread_pool_worker.rb +0 -73
- data/lib/concurrent/logging.rb +0 -20
- data/lib/concurrent/obligation.rb +0 -171
- data/lib/concurrent/observable.rb +0 -73
- data/lib/concurrent/options_parser.rb +0 -48
- data/lib/concurrent/utility/processor_count.rb +0 -152
- data/lib/extension_helper.rb +0 -37
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
require 'concurrent/utility/native_extension_loader'
|
2
|
+
require 'concurrent/synchronization'
|
2
3
|
|
3
4
|
module Concurrent
|
4
5
|
|
@@ -21,7 +22,10 @@ module Concurrent
|
|
21
22
|
# 4.520000 0.030000 4.550000 ( 1.187000)
|
22
23
|
#
|
23
24
|
# @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicLong.html java.util.concurrent.atomic.AtomicLong
|
24
|
-
|
25
|
+
#
|
26
|
+
# @!visibility private
|
27
|
+
# @!macro internal_implementation_note
|
28
|
+
class MutexAtomicFixnum < Synchronization::Object
|
25
29
|
|
26
30
|
# http://stackoverflow.com/questions/535721/ruby-max-integer
|
27
31
|
MIN_VALUE = -(2**(0.size * 8 - 2))
|
@@ -31,12 +35,11 @@ module Concurrent
|
|
31
35
|
#
|
32
36
|
# Creates a new `AtomicFixnum` with the given initial value.
|
33
37
|
#
|
34
|
-
# @param [Fixnum]
|
38
|
+
# @param [Fixnum] initial the initial value
|
35
39
|
# @raise [ArgumentError] if the initial value is not a `Fixnum`
|
36
|
-
def initialize(
|
37
|
-
|
38
|
-
|
39
|
-
@mutex = Mutex.new
|
40
|
+
def initialize(initial = 0)
|
41
|
+
super()
|
42
|
+
synchronize { ns_initialize(initial) }
|
40
43
|
end
|
41
44
|
|
42
45
|
# @!macro [attach] atomic_fixnum_method_value_get
|
@@ -45,10 +48,7 @@ module Concurrent
|
|
45
48
|
#
|
46
49
|
# @return [Fixnum] the current value
|
47
50
|
def value
|
48
|
-
@
|
49
|
-
@value
|
50
|
-
ensure
|
51
|
-
@mutex.unlock
|
51
|
+
synchronize { @value }
|
52
52
|
end
|
53
53
|
|
54
54
|
# @!macro [attach] atomic_fixnum_method_value_set
|
@@ -61,11 +61,7 @@ module Concurrent
|
|
61
61
|
#
|
62
62
|
# @raise [ArgumentError] if the new value is not a `Fixnum`
|
63
63
|
def value=(value)
|
64
|
-
|
65
|
-
@mutex.lock
|
66
|
-
@value = value
|
67
|
-
ensure
|
68
|
-
@mutex.unlock
|
64
|
+
synchronize { ns_set(value) }
|
69
65
|
end
|
70
66
|
|
71
67
|
# @!macro [attach] atomic_fixnum_method_increment
|
@@ -74,10 +70,7 @@ module Concurrent
|
|
74
70
|
#
|
75
71
|
# @return [Fixnum] the current value after incrementation
|
76
72
|
def increment
|
77
|
-
@
|
78
|
-
@value += 1
|
79
|
-
ensure
|
80
|
-
@mutex.unlock
|
73
|
+
synchronize { ns_set(@value + 1) }
|
81
74
|
end
|
82
75
|
|
83
76
|
alias_method :up, :increment
|
@@ -88,115 +81,94 @@ module Concurrent
|
|
88
81
|
#
|
89
82
|
# @return [Fixnum] the current value after decrementation
|
90
83
|
def decrement
|
91
|
-
@
|
92
|
-
@value -= 1
|
93
|
-
ensure
|
94
|
-
@mutex.unlock
|
84
|
+
synchronize { ns_set(@value -1) }
|
95
85
|
end
|
96
86
|
|
97
87
|
alias_method :down, :decrement
|
98
88
|
|
99
89
|
# @!macro [attach] atomic_fixnum_method_compare_and_set
|
100
|
-
#
|
90
|
+
#
|
101
91
|
# Atomically sets the value to the given updated value if the current
|
102
92
|
# value == the expected value.
|
103
93
|
#
|
104
94
|
# @param [Fixnum] expect the expected value
|
105
95
|
# @param [Fixnum] update the new value
|
106
96
|
#
|
107
|
-
# @return [
|
97
|
+
# @return [Fixnum] true if the value was updated else false
|
108
98
|
def compare_and_set(expect, update)
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
99
|
+
synchronize do
|
100
|
+
if @value == expect
|
101
|
+
@value = update
|
102
|
+
true
|
103
|
+
else
|
104
|
+
false
|
105
|
+
end
|
115
106
|
end
|
116
|
-
ensure
|
117
|
-
@mutex.unlock
|
118
107
|
end
|
119
|
-
end
|
120
|
-
|
121
|
-
if RUBY_PLATFORM == 'java'
|
122
|
-
|
123
|
-
# @!macro atomic_fixnum
|
124
|
-
class JavaAtomicFixnum
|
125
108
|
|
126
|
-
|
127
|
-
MAX_VALUE = Java::JavaLang::Long::MAX_VALUE
|
109
|
+
protected
|
128
110
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
end
|
134
|
-
|
135
|
-
# @!macro atomic_fixnum_method_value_get
|
136
|
-
def value
|
137
|
-
@atomic.get
|
138
|
-
end
|
139
|
-
|
140
|
-
# @!macro atomic_fixnum_method_value_set
|
141
|
-
def value=(value)
|
142
|
-
raise ArgumentError.new('value must be a Fixnum') unless value.is_a?(Fixnum)
|
143
|
-
@atomic.set(value)
|
144
|
-
end
|
145
|
-
|
146
|
-
# @!macro atomic_fixnum_method_increment
|
147
|
-
def increment
|
148
|
-
@atomic.increment_and_get
|
149
|
-
end
|
150
|
-
alias_method :up, :increment
|
111
|
+
# @!visibility private
|
112
|
+
def ns_initialize(initial)
|
113
|
+
ns_set(initial)
|
114
|
+
end
|
151
115
|
|
152
|
-
|
153
|
-
def decrement
|
154
|
-
@atomic.decrement_and_get
|
155
|
-
end
|
156
|
-
alias_method :down, :decrement
|
116
|
+
private
|
157
117
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
118
|
+
# @!visibility private
|
119
|
+
def ns_set(value)
|
120
|
+
range_check!(value)
|
121
|
+
@value = value
|
162
122
|
end
|
163
123
|
|
164
|
-
# @!
|
165
|
-
|
124
|
+
# @!visibility private
|
125
|
+
def range_check!(value)
|
126
|
+
if !value.is_a?(Fixnum)
|
127
|
+
raise ArgumentError.new('value value must be a Fixnum')
|
128
|
+
elsif value > MAX_VALUE
|
129
|
+
raise RangeError.new("#{value} is greater than the maximum value of #{MAX_VALUE}")
|
130
|
+
elsif value < MIN_VALUE
|
131
|
+
raise RangeError.new("#{value} is less than the maximum value of #{MIN_VALUE}")
|
132
|
+
else
|
133
|
+
value
|
134
|
+
end
|
166
135
|
end
|
136
|
+
end
|
167
137
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
138
|
+
# @!visibility private
|
139
|
+
# @!macro internal_implementation_note
|
140
|
+
AtomicFixnumImplementation = case
|
141
|
+
when Concurrent.on_jruby?
|
142
|
+
JavaAtomicFixnum
|
143
|
+
when defined?(CAtomicFixnum)
|
144
|
+
CAtomicFixnum
|
145
|
+
else
|
146
|
+
MutexAtomicFixnum
|
147
|
+
end
|
148
|
+
private_constant :AtomicFixnumImplementation
|
149
|
+
|
150
|
+
# @!macro atomic_fixnum
|
151
|
+
#
|
152
|
+
# @see Concurrent::MutexAtomicFixnum
|
153
|
+
class AtomicFixnum < AtomicFixnumImplementation
|
172
154
|
|
173
|
-
|
174
|
-
|
155
|
+
# @!method initialize(initial = 0)
|
156
|
+
# @!macro atomic_fixnum_method_initialize
|
175
157
|
|
176
|
-
|
177
|
-
|
158
|
+
# @!method value
|
159
|
+
# @!macro atomic_fixnum_method_value_get
|
178
160
|
|
179
|
-
|
180
|
-
|
161
|
+
# @!method value=(value)
|
162
|
+
# @!macro atomic_fixnum_method_value_set
|
181
163
|
|
182
|
-
|
183
|
-
|
164
|
+
# @!method increment
|
165
|
+
# @!macro atomic_fixnum_method_increment
|
184
166
|
|
185
|
-
|
186
|
-
|
167
|
+
# @!method decrement
|
168
|
+
# @!macro atomic_fixnum_method_decrement
|
187
169
|
|
188
|
-
|
189
|
-
|
190
|
-
end
|
170
|
+
# @!method compare_and_set(expect, update)
|
171
|
+
# @!macro atomic_fixnum_method_compare_and_set
|
191
172
|
|
192
|
-
# @!macro atomic_fixnum
|
193
|
-
class AtomicFixnum < CAtomicFixnum
|
194
|
-
end
|
195
|
-
|
196
|
-
else
|
197
|
-
|
198
|
-
# @!macro atomic_fixnum
|
199
|
-
class AtomicFixnum < MutexAtomicFixnum
|
200
|
-
end
|
201
173
|
end
|
202
174
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'concurrent/utility/native_extension_loader'
|
2
|
+
require 'concurrent/utility/engine'
|
3
|
+
require 'concurrent/atomic_reference/concurrent_update_error'
|
4
|
+
require 'concurrent/atomic_reference/mutex_atomic'
|
5
|
+
|
6
|
+
begin
|
7
|
+
# force fallback impl with FORCE_ATOMIC_FALLBACK=1
|
8
|
+
if /[^0fF]/ =~ ENV['FORCE_ATOMIC_FALLBACK']
|
9
|
+
ruby_engine = 'mutex_atomic'
|
10
|
+
else
|
11
|
+
ruby_engine = Concurrent.ruby_engine
|
12
|
+
end
|
13
|
+
|
14
|
+
require "concurrent/atomic_reference/#{ruby_engine}"
|
15
|
+
rescue LoadError
|
16
|
+
#warn 'Compiled extensions not installed, pure Ruby Atomic will be used.'
|
17
|
+
end
|
18
|
+
|
19
|
+
if defined? Concurrent::JavaAtomicReference
|
20
|
+
|
21
|
+
# @!macro atomic_reference
|
22
|
+
class Concurrent::AtomicReference < Concurrent::JavaAtomicReference
|
23
|
+
end
|
24
|
+
|
25
|
+
elsif defined? Concurrent::RbxAtomicReference
|
26
|
+
|
27
|
+
# @!macro atomic_reference
|
28
|
+
class Concurrent::AtomicReference < Concurrent::RbxAtomicReference
|
29
|
+
end
|
30
|
+
|
31
|
+
elsif defined? Concurrent::CAtomicReference
|
32
|
+
|
33
|
+
# @!macro atomic_reference
|
34
|
+
class Concurrent::AtomicReference < Concurrent::CAtomicReference
|
35
|
+
end
|
36
|
+
|
37
|
+
else
|
38
|
+
|
39
|
+
# @!macro atomic_reference
|
40
|
+
class Concurrent::AtomicReference < Concurrent::MutexAtomicReference
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
module Concurrent
|
45
|
+
|
46
|
+
# @see Concurrent::AtomicReference
|
47
|
+
# @deprecated Use Concurrent::AtomicReference instead.
|
48
|
+
Atomic = AtomicReference
|
49
|
+
end
|
@@ -1,14 +1,21 @@
|
|
1
|
+
require 'concurrent/utility/monotonic_time'
|
2
|
+
require 'concurrent/concern/deprecation'
|
3
|
+
|
1
4
|
module Concurrent
|
2
5
|
|
3
|
-
# Condition is a better implementation of standard Ruby ConditionVariable.
|
4
|
-
#
|
5
|
-
# Condition::Result which make possible to know if waiting thread has been
|
6
|
-
# by an another thread (using #signal or #broadcast) or due to
|
6
|
+
# Condition is a better implementation of standard Ruby ConditionVariable. The
|
7
|
+
# biggest difference is the wait return value: Condition#wait returns
|
8
|
+
# Condition::Result which make possible to know if waiting thread has been
|
9
|
+
# woken up by an another thread (using #signal or #broadcast) or due to
|
10
|
+
# timeout.
|
11
|
+
#
|
12
|
+
# Every #wait must be guarded by a locked Mutex or a ThreadError will be
|
13
|
+
# risen. Although it's not mandatory, it's recommended to call also #signal
|
14
|
+
# and #broadcast within the same mutex
|
7
15
|
#
|
8
|
-
#
|
9
|
-
# Although it's not mandatory, it's recommended to call also #signal and #broadcast within
|
10
|
-
# the same mutex
|
16
|
+
# @deprecated
|
11
17
|
class Condition
|
18
|
+
include Concern::Deprecation
|
12
19
|
|
13
20
|
class Result
|
14
21
|
def initialize(remaining_time)
|
@@ -17,12 +24,14 @@ module Concurrent
|
|
17
24
|
|
18
25
|
attr_reader :remaining_time
|
19
26
|
|
20
|
-
# @return [Boolean] true if current thread has been waken up by a #signal
|
27
|
+
# @return [Boolean] true if current thread has been waken up by a #signal
|
28
|
+
# or a #broadcast call , otherwise false
|
21
29
|
def woken_up?
|
22
30
|
@remaining_time.nil? || @remaining_time > 0
|
23
31
|
end
|
24
32
|
|
25
|
-
# @return [Boolean] true if current thread has been waken up due to a
|
33
|
+
# @return [Boolean] true if current thread has been waken up due to a
|
34
|
+
# timeout, otherwise false
|
26
35
|
def timed_out?
|
27
36
|
@remaining_time != nil && @remaining_time <= 0
|
28
37
|
end
|
@@ -32,20 +41,23 @@ module Concurrent
|
|
32
41
|
end
|
33
42
|
|
34
43
|
def initialize
|
44
|
+
deprecated 'Will be replaced with Synchronization::Object in v1.0.'
|
35
45
|
@condition = ConditionVariable.new
|
36
46
|
end
|
37
47
|
|
38
48
|
# @param [Mutex] mutex the locked mutex guarding the wait
|
39
49
|
# @param [Object] timeout nil means no timeout
|
40
50
|
# @return [Result]
|
51
|
+
#
|
52
|
+
# @!macro monotonic_clock_warning
|
41
53
|
def wait(mutex, timeout = nil)
|
42
|
-
start_time =
|
54
|
+
start_time = Concurrent.monotonic_time
|
43
55
|
@condition.wait(mutex, timeout)
|
44
56
|
|
45
57
|
if timeout.nil?
|
46
58
|
Result.new(nil)
|
47
59
|
else
|
48
|
-
Result.new(start_time + timeout -
|
60
|
+
Result.new(start_time + timeout - Concurrent.monotonic_time)
|
49
61
|
end
|
50
62
|
end
|
51
63
|
|
@@ -62,6 +74,5 @@ module Concurrent
|
|
62
74
|
@condition.broadcast
|
63
75
|
true
|
64
76
|
end
|
65
|
-
|
66
77
|
end
|
67
78
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'concurrent/
|
1
|
+
require 'concurrent/synchronization'
|
2
2
|
|
3
3
|
module Concurrent
|
4
4
|
|
@@ -11,7 +11,10 @@ module Concurrent
|
|
11
11
|
# method. Each of the other threads calls `#count_down` when done with its work.
|
12
12
|
# When the latch counter reaches zero the waiting thread is unblocked and continues
|
13
13
|
# with its work. A `CountDownLatch` can be used only once. Its value cannot be reset.
|
14
|
-
|
14
|
+
#
|
15
|
+
# @!visibility private
|
16
|
+
# @!macro internal_implementation_note
|
17
|
+
class PureCountDownLatch < Synchronization::Object
|
15
18
|
|
16
19
|
# @!macro [attach] count_down_latch_method_initialize
|
17
20
|
#
|
@@ -20,13 +23,12 @@ module Concurrent
|
|
20
23
|
# @param [Fixnum] count the initial count
|
21
24
|
#
|
22
25
|
# @raise [ArgumentError] if `count` is not an integer or is less than zero
|
23
|
-
def initialize(count)
|
26
|
+
def initialize(count = 1)
|
24
27
|
unless count.is_a?(Fixnum) && count >= 0
|
25
28
|
raise ArgumentError.new('count must be in integer greater than or equal zero')
|
26
29
|
end
|
27
|
-
|
28
|
-
|
29
|
-
@count = count
|
30
|
+
super()
|
31
|
+
synchronize { ns_initialize count }
|
30
32
|
end
|
31
33
|
|
32
34
|
# @!macro [attach] count_down_latch_method_wait
|
@@ -37,15 +39,7 @@ module Concurrent
|
|
37
39
|
# to block indefinitely
|
38
40
|
# @return [Boolean] `true` if the `count` reaches zero else false on `timeout`
|
39
41
|
def wait(timeout = nil)
|
40
|
-
|
41
|
-
|
42
|
-
remaining = Condition::Result.new(timeout)
|
43
|
-
while @count > 0 && remaining.can_wait?
|
44
|
-
remaining = @condition.wait(@mutex, remaining.remaining_time)
|
45
|
-
end
|
46
|
-
|
47
|
-
@count == 0
|
48
|
-
end
|
42
|
+
synchronize { ns_wait_until(timeout) { @count == 0 } }
|
49
43
|
end
|
50
44
|
|
51
45
|
# @!macro [attach] count_down_latch_method_count_down
|
@@ -53,9 +47,9 @@ module Concurrent
|
|
53
47
|
# Signal the latch to decrement the counter. Will signal all blocked threads when
|
54
48
|
# the `count` reaches zero.
|
55
49
|
def count_down
|
56
|
-
|
50
|
+
synchronize do
|
57
51
|
@count -= 1 if @count > 0
|
58
|
-
|
52
|
+
ns_broadcast if @count == 0
|
59
53
|
end
|
60
54
|
end
|
61
55
|
|
@@ -65,17 +59,25 @@ module Concurrent
|
|
65
59
|
#
|
66
60
|
# @return [Fixnum] the current value of the counter
|
67
61
|
def count
|
68
|
-
|
62
|
+
synchronize { @count }
|
63
|
+
end
|
64
|
+
|
65
|
+
protected
|
66
|
+
|
67
|
+
def ns_initialize(count)
|
68
|
+
@count = count
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
-
if
|
72
|
+
if Concurrent.on_jruby?
|
73
73
|
|
74
74
|
# @!macro count_down_latch
|
75
|
+
# @!visibility private
|
76
|
+
# @!macro internal_implementation_note
|
75
77
|
class JavaCountDownLatch
|
76
78
|
|
77
79
|
# @!macro count_down_latch_method_initialize
|
78
|
-
def initialize(count)
|
80
|
+
def initialize(count = 1)
|
79
81
|
unless count.is_a?(Fixnum) && count >= 0
|
80
82
|
raise ArgumentError.new('count must be in integer greater than or equal zero')
|
81
83
|
end
|
@@ -110,7 +112,7 @@ module Concurrent
|
|
110
112
|
else
|
111
113
|
|
112
114
|
# @!macro count_down_latch
|
113
|
-
class CountDownLatch <
|
115
|
+
class CountDownLatch < PureCountDownLatch
|
114
116
|
end
|
115
117
|
end
|
116
118
|
end
|