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