1- require 'thread'
21require 'concurrent/collection/copy_on_write_observer_set'
32require 'concurrent/concern/dereferenceable'
43require 'concurrent/concern/observable'
54require 'concurrent/concern/logging'
65require 'concurrent/executor/executor'
6+ require 'concurrent/synchronization'
77
88module Concurrent
99
@@ -80,7 +80,7 @@ module Concurrent
8080 # @return [Fixnum] the maximum number of seconds before an update is cancelled
8181 #
8282 # @!macro edge_warning
83- class Agent
83+ class Agent < Synchronization :: Object
8484 include Concern ::Dereferenceable
8585 include Concern ::Observable
8686 include Concern ::Logging
@@ -93,15 +93,8 @@ class Agent
9393 #
9494 # @!macro executor_and_deref_options
9595 def initialize ( initial , opts = { } )
96- @value = initial
97- @rescuers = [ ]
98- @validator = Proc . new { |result | true }
99- self . observers = Collection ::CopyOnWriteObserverSet . new
100- @serialized_execution = SerializedExecution . new
101- @io_executor = Executor . executor_from_options ( opts ) || Concurrent . global_io_executor
102- @fast_executor = Executor . executor_from_options ( opts ) || Concurrent . global_fast_executor
103- init_mutex
104- set_deref_options ( opts )
96+ super ( )
97+ synchronize { ns_initialize ( initial , opts ) }
10598 end
10699
107100 # Specifies a block fast to be performed when an update fast raises
@@ -127,17 +120,15 @@ def initialize(initial, opts = {})
127120 # #=> puts "Pow!"
128121 def rescue ( clazz = StandardError , &block )
129122 unless block . nil?
130- mutex . synchronize do
131- @rescuers << Rescuer . new ( clazz , block )
132- end
123+ synchronize { @rescuers << Rescuer . new ( clazz , block ) }
133124 end
134125 self
135126 end
136127
137128 alias_method :catch , :rescue
138129 alias_method :on_error , :rescue
139130
140- # A block fast to be performed after every update to validate if the new
131+ # A block task to be performed after every update to validate if the new
141132 # value is valid. If the new value is not valid then the current value is not
142133 # updated. If no validator is provided then all updates are considered valid.
143134 #
@@ -148,12 +139,7 @@ def rescue(clazz = StandardError, &block)
148139 def validate ( &block )
149140
150141 unless block . nil?
151- begin
152- mutex . lock
153- @validator = block
154- ensure
155- mutex . unlock
156- end
142+ synchronize { @validator = block }
157143 end
158144 self
159145 end
@@ -208,6 +194,20 @@ def await(timeout = nil)
208194 done . wait timeout
209195 end
210196
197+ protected
198+
199+ def ns_initialize ( initial , opts )
200+ init_mutex ( self )
201+ @value = initial
202+ @rescuers = [ ]
203+ @validator = Proc . new { |result | true }
204+ self . observers = Collection ::CopyOnWriteObserverSet . new
205+ @serialized_execution = SerializedExecution . new
206+ @io_executor = Executor . executor_from_options ( opts ) || Concurrent . global_io_executor
207+ @fast_executor = Executor . executor_from_options ( opts ) || Concurrent . global_fast_executor
208+ set_deref_options ( opts )
209+ end
210+
211211 private
212212
213213 def post_on ( executor , &block )
@@ -221,7 +221,7 @@ def post_on(executor, &block)
221221
222222 # @!visibility private
223223 def try_rescue ( ex ) # :nodoc:
224- rescuer = mutex . synchronize do
224+ rescuer = synchronize do
225225 @rescuers . find { |r | ex . is_a? ( r . clazz ) }
226226 end
227227 rescuer . block . call ( ex ) if rescuer
@@ -232,7 +232,7 @@ def try_rescue(ex) # :nodoc:
232232
233233 # @!visibility private
234234 def work ( &handler ) # :nodoc:
235- validator , value = mutex . synchronize { [ @validator , @value ] }
235+ validator , value = synchronize { [ @validator , @value ] }
236236
237237 begin
238238 result = handler . call ( value )
@@ -241,14 +241,11 @@ def work(&handler) # :nodoc:
241241 exception = ex
242242 end
243243
244- begin
245- mutex . lock
246- should_notify = if !exception && valid
247- @value = result
248- true
249- end
250- ensure
251- mutex . unlock
244+ should_notify = synchronize do
245+ if !exception && valid
246+ @value = result
247+ true
248+ end
252249 end
253250
254251 if should_notify
0 commit comments