Class: Concurrent::AtomicMarkableReference
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
|
|
Instance Chain:
|
|
Inherits: |
Concurrent::Synchronization::Object
|
Defined in: | lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb |
Overview
An atomic reference which maintains an object reference along with a mark bit that can be updated atomically.
Class Attribute Summary
Synchronization::Object
- Inherited
Class Method Summary
Synchronization::Object
- Inherited
.atomic_attribute?, .atomic_attributes, | |
.attr_atomic | Creates methods for reading and writing to a instance variable with volatile (Java) semantic as |
.attr_volatile | Creates methods for reading and writing (as |
.ensure_safe_initialization_when_final_fields_are_present | For testing purposes, quite slow. |
.new | Has to be called by children. |
.safe_initialization!, .define_initialize_atomic_fields |
Synchronization::AbstractObject
- Inherited
Instance Attribute Summary
Instance Method Summary
-
#compare_and_set(expected_val, new_val, expected_mark, new_mark) ⇒ Boolean
(also: #compare_and_swap)
Atomically sets the value and mark to the given updated value and mark given both:
-
#compare_and_swap(expected_val, new_val, expected_mark, new_mark)
Alias for #compare_and_set.
-
#get ⇒ Array
Gets the current reference and marked values.
-
#mark ⇒ Boolean
(also: #marked?)
Gets the current marked value.
-
#set(new_val, new_mark) ⇒ Array
Unconditionally sets to the given value of both the reference and the mark.
-
#try_update {|Object| ... } ⇒ Array
Pass the current value to the given block, replacing it with the block’s result.
-
#try_update! {|Object| ... } ⇒ Array
Pass the current value to the given block, replacing it with the block’s result.
-
#update {|Object| ... } ⇒ Array
Pass the current value and marked state to the given block, replacing it with the block’s results.
-
#value ⇒ Object
Gets the current value of the reference.
-
#compare_and_set_reference(expected_reference, new_reference) ⇒ true, false
private
Sets the reference to new_reference if the current reference is expected_reference.
- #immutable_array(*args) private
- #reference ⇒ Object private
-
#reference=(new_reference) ⇒ Object
private
Set
the reference. -
#swap_reference(new_reference) ⇒ Object
private
Set
the reference to new_reference and return the old reference. -
#update_reference {|Object| ... } ⇒ Object
private
Updates the reference using the block.
Synchronization::Object
- Inherited
Synchronization::Volatile
- Included
Synchronization::AbstractObject
- Inherited
Constructor Details
.new(value = nil, mark = false) ⇒ AtomicMarkableReference
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 15
def initialize(value = nil, mark = false) super() self.reference = immutable_array(value, mark) end
Instance Attribute Details
#marked? (readonly)
Alias for #mark.
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 82
alias_method :marked?, :mark
Instance Method Details
#compare_and_set(expected_val, new_val, expected_mark, new_mark) ⇒ Boolean
Also known as: #compare_and_swap
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 33
def compare_and_set(expected_val, new_val, expected_mark, new_mark) # Memoize a valid reference to the current AtomicReference for # later comparison. current = reference curr_val, curr_mark = current # Ensure that that the expected marks match. return false unless expected_mark == curr_mark if expected_val.is_a? Numeric # If the object is a numeric, we need to ensure we are comparing # the numerical values return false unless expected_val == curr_val else # Otherwise, we need to ensure we are comparing the object identity. # Theoretically, this could be incorrect if a user monkey-patched # `Object#equal?`, but they should know that they are playing with # fire at that point. return false unless expected_val.equal? curr_val end prospect = immutable_array(new_val, new_mark) compare_and_set_reference current, prospect end
#compare_and_set_reference(expected_reference, new_reference) ⇒ true
, false
(private)
Sets the reference to new_reference if the current reference is expected_reference
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 12
attr_atomic(:reference)
#compare_and_swap(expected_val, new_val, expected_mark, new_mark)
Alias for #compare_and_set.
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 59
alias_method :compare_and_swap, :compare_and_set
#get ⇒ Array
Gets the current reference and marked values.
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 64
def get reference end
#immutable_array(*args) (private)
[ GitHub ]# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 163
def immutable_array(*args) args.freeze end
#mark ⇒ Boolean
Also known as: #marked?
Gets the current marked value
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 78
def mark reference[1] end
#reference ⇒ Object (private)
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 12
attr_atomic(:reference)
#reference=(new_reference) ⇒ Object (private)
Set
the reference.
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 12
attr_atomic(:reference)
#set(new_val, new_mark) ⇒ Array
Unconditionally sets to the given value of both the reference and the mark.
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 91
def set(new_val, new_mark) self.reference = immutable_array(new_val, new_mark) end
#swap_reference(new_reference) ⇒ Object (private)
Set
the reference to new_reference and return the old reference.
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 12
attr_atomic(:reference)
#try_update {|Object| ... } ⇒ Array
Pass the current value to the given block, replacing it with the block’s result. Simply return nil if update fails.
the update failed
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 152
def try_update old_val, old_mark = reference new_val, new_mark = yield old_val, old_mark return unless compare_and_set old_val, new_val, old_mark, new_mark immutable_array(new_val, new_mark) end
#try_update! {|Object| ... } ⇒ Array
Pass the current value to the given block, replacing it with the block’s result. Raise an exception if the update fails.
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 128
def try_update! old_val, old_mark = reference new_val, new_mark = yield old_val, old_mark unless compare_and_set old_val, new_val, old_mark, new_mark fail ::Concurrent::ConcurrentUpdateError, 'AtomicMarkableReference: Update failed due to race condition.', 'Note: If you would like to guarantee an update, please use ' + 'the `AtomicMarkableReference#update` method.' end immutable_array(new_val, new_mark) end
#update {|Object| ... } ⇒ Array
Pass the current value and marked state to the given block, replacing it with the block’s results. May retry if the value changes during the block’s execution.
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 105
def update loop do old_val, old_mark = reference new_val, new_mark = yield old_val, old_mark if compare_and_set old_val, new_val, old_mark, new_mark return immutable_array(new_val, new_mark) end end end
#update_reference {|Object| ... } ⇒ Object (private)
Updates the reference using the block.
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 12
attr_atomic(:reference)
#value ⇒ Object
Gets the current value of the reference
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 71
def value reference[0] end