11require 'concurrent/atomic/atomic_reference'
22require 'concurrent/collection/copy_on_notify_observer_set'
33require 'concurrent/concern/observable'
4+ require 'concurrent/synchronization'
45
56# @!macro [new] thread_safe_variable_comparison
67#
@@ -90,9 +91,13 @@ module Concurrent
9091 #
9192 # @see http://clojure.org/atoms Clojure Atoms
9293 # @see http://clojure.org/state Values and Change - Clojure's approach to Identity and State
93- class Atom
94+ class Atom < Synchronization :: Object
9495 include Concern ::Observable
9596
97+ safe_initialization!
98+ private ( *attr_volatile_with_cas ( :value ) )
99+ public :value
100+
96101 # Create a new atom with the given initial value.
97102 #
98103 # @param [Object] value The initial value
@@ -106,18 +111,15 @@ class Atom
106111 #
107112 # @raise [ArgumentError] if the validator is not a `Proc` (when given)
108113 def initialize ( value , opts = { } )
109- @validator = opts . fetch ( :validator , -> v { true } )
114+ @Validator = opts . fetch ( :validator , -> v { true } )
110115 self . observers = Collection ::CopyOnNotifyObserverSet . new
111- @state = AtomicReference . new ( value )
116+ super ( value )
112117 end
113118
114119 # @!method value
115120 # The current value of the atom.
116121 #
117122 # @return [Object] The current value.
118- def value
119- @state . get
120- end
121123
122124 alias_method :deref , :value
123125
@@ -158,7 +160,7 @@ def swap(*args)
158160 begin
159161 new_value = yield ( old_value , *args )
160162 break old_value unless valid? ( new_value )
161- break new_value if @state . compare_and_set ( old_value , new_value )
163+ break new_value if compare_and_set ( old_value , new_value )
162164 rescue
163165 break old_value
164166 end
@@ -175,7 +177,7 @@ def swap(*args)
175177 #
176178 # @return [Boolean] True if the value is changed else false.
177179 def compare_and_set ( old_value , new_value )
178- if valid? ( new_value ) && @state . compare_and_set ( old_value , new_value )
180+ if valid? ( new_value ) && compare_and_set_value ( old_value , new_value )
179181 observers . notify_observers ( Time . now , old_value , new_value )
180182 true
181183 else
@@ -194,7 +196,7 @@ def compare_and_set(old_value, new_value)
194196 def reset ( new_value )
195197 old_value = value
196198 if valid? ( new_value )
197- @state . set ( new_value )
199+ self . value = new_value
198200 observers . notify_observers ( Time . now , old_value , new_value )
199201 new_value
200202 else
@@ -210,7 +212,7 @@ def reset(new_value)
210212 # @return [Boolean] false if the validator function returns false or raises
211213 # an exception else true
212214 def valid? ( new_value )
213- @validator . call ( new_value )
215+ @Validator . call ( new_value )
214216 rescue
215217 false
216218 end
0 commit comments