1
1
require 'concurrent/atomic/atomic_reference'
2
2
require 'concurrent/collection/copy_on_notify_observer_set'
3
3
require 'concurrent/concern/observable'
4
- require 'concurrent/synchronization'
5
4
6
5
# @!macro [new] thread_safe_variable_comparison
7
6
#
@@ -91,13 +90,9 @@ module Concurrent
91
90
#
92
91
# @see http://clojure.org/atoms Clojure Atoms
93
92
# @see http://clojure.org/state Values and Change - Clojure's approach to Identity and State
94
- class Atom < Synchronization :: Object
93
+ class Atom
95
94
include Concern ::Observable
96
95
97
- safe_initialization!
98
- private ( *attr_volatile_with_cas ( :value ) )
99
- public :value
100
-
101
96
# Create a new atom with the given initial value.
102
97
#
103
98
# @param [Object] value The initial value
@@ -111,15 +106,18 @@ class Atom < Synchronization::Object
111
106
#
112
107
# @raise [ArgumentError] if the validator is not a `Proc` (when given)
113
108
def initialize ( value , opts = { } )
114
- @Validator = opts . fetch ( :validator , -> v { true } )
109
+ @validator = opts . fetch ( :validator , -> v { true } )
115
110
self . observers = Collection ::CopyOnNotifyObserverSet . new
116
- super ( value )
111
+ @state = AtomicReference . new ( value )
117
112
end
118
113
119
114
# @!method value
120
115
# The current value of the atom.
121
116
#
122
117
# @return [Object] The current value.
118
+ def value
119
+ @state . get
120
+ end
123
121
124
122
alias_method :deref , :value
125
123
@@ -160,7 +158,7 @@ def swap(*args)
160
158
begin
161
159
new_value = yield ( old_value , *args )
162
160
break old_value unless valid? ( new_value )
163
- break new_value if compare_and_set ( old_value , new_value )
161
+ break new_value if @state . compare_and_set ( old_value , new_value )
164
162
rescue
165
163
break old_value
166
164
end
@@ -177,7 +175,7 @@ def swap(*args)
177
175
#
178
176
# @return [Boolean] True if the value is changed else false.
179
177
def compare_and_set ( old_value , new_value )
180
- if valid? ( new_value ) && compare_and_set_value ( old_value , new_value )
178
+ if valid? ( new_value ) && @state . compare_and_set ( old_value , new_value )
181
179
observers . notify_observers ( Time . now , old_value , new_value )
182
180
true
183
181
else
@@ -196,7 +194,7 @@ def compare_and_set(old_value, new_value)
196
194
def reset ( new_value )
197
195
old_value = value
198
196
if valid? ( new_value )
199
- self . value = new_value
197
+ @state . set ( new_value )
200
198
observers . notify_observers ( Time . now , old_value , new_value )
201
199
new_value
202
200
else
@@ -212,7 +210,7 @@ def reset(new_value)
212
210
# @return [Boolean] false if the validator function returns false or raises
213
211
# an exception else true
214
212
def valid? ( new_value )
215
- @Validator . call ( new_value )
213
+ @validator . call ( new_value )
216
214
rescue
217
215
false
218
216
end
0 commit comments