Method: Concurrent::Atom#swap
- Defined in:
- lib/concurrent/atom.rb
#swap(*args) {|value, args| ... } ⇒ Object
The given block may be called multiple times, and thus should be free of side effects.
Atomically swaps the value of atom using the given block. The current value will be passed to the block, as will any arguments passed as arguments to the function. The new value will be validated against the (optional) validator proc given at construction. If validation fails the value will not be changed.
Internally, #swap reads the current value, applies the block to it, and attempts to compare-and-set it in. Since another thread may have changed the value in the intervening time, it may have to retry, and does so in a spin loop. The net effect is that the value will always be the result of the application of the supplied block to a current value, atomically. However, because the block might be called multiple times, it must be free of side effects.
156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/concurrent/atom.rb', line 156 def swap(*args) raise ArgumentError.new('no block given') unless block_given? loop do old_value = value begin new_value = yield(old_value, *args) break old_value unless valid?(new_value) break new_value if compare_and_set(old_value, new_value) rescue break old_value end end end |