Class: Concurrent::Synchronization::Object
- Inherits:
-
ObjectImplementation
- Object
- Concurrent::Synchronization::Object
- Defined in:
- lib/concurrent-ruby/concurrent/synchronization/object.rb
Overview
Abstract object providing final, volatile, ans CAS extensions to build other concurrent abstractions.
- final instance variables see Object.safe_initialization!
- volatile instance variables see Object.attr_volatile
- volatile instance variables see Object.attr_atomic
Direct Known Subclasses
Atom, AtomicMarkableReference, Cancellation, Channel::Tick, Edge::LockFreeLinkedSet::Node, ErlangActor::Environment, ErlangActor::Pid, LazyRegister, LockFreeQueue::Node, LockFreeStack, MVar, Maybe, ProcessingActor, Promises::AbstractEventFuture, Promises::Channel, ReadWriteLock, ReentrantReadWriteLock, TVar, Throttle, WrappingExecutor
Class Method Summary collapse
-
.atomic_attribute?(name) ⇒ true, false
Is the attribute with name atomic?.
-
.atomic_attributes(inherited = true) ⇒ ::Array<Symbol>
Returns defined volatile with CAS fields on this class.
-
.attr_atomic(*names) ⇒ ::Array<Symbol>
Creates methods for reading and writing to a instance variable with volatile (Java) semantic as Object.attr_volatile does.
-
.attr_volatile(*names) ⇒ ::Array<Symbol>
Creates methods for reading and writing (as
attr_accessor
does) to a instance variable with volatile (Java) semantic. -
.ensure_safe_initialization_when_final_fields_are_present ⇒ true
For testing purposes, quite slow.
-
.safe_initialization! ⇒ true
By calling this method on a class, it and all its children are marked to be constructed safely.
-
.safe_initialization? ⇒ true, false
If this class is safely initialized.
Instance Method Summary collapse
-
#initialize ⇒ Object
constructor
Has to be called by children.
Constructor Details
#initialize ⇒ Object
Has to be called by children.
36 37 38 39 |
# File 'lib/concurrent-ruby/concurrent/synchronization/object.rb', line 36 def initialize super __initialize_atomic_fields__ end |
Class Method Details
.atomic_attribute?(name) ⇒ true, false
Returns is the attribute with name atomic?.
157 158 159 |
# File 'lib/concurrent-ruby/concurrent/synchronization/object.rb', line 157 def self.atomic_attribute?(name) atomic_attributes.include? name end |
.atomic_attributes(inherited = true) ⇒ ::Array<Symbol>
Returns defined volatile with CAS fields on this class.
151 152 153 154 |
# File 'lib/concurrent-ruby/concurrent/synchronization/object.rb', line 151 def self.atomic_attributes(inherited = true) @__atomic_fields__ ||= [] ((superclass.atomic_attributes if superclass.respond_to?(:atomic_attributes) && inherited) || []) + @__atomic_fields__ end |
.attr_atomic(*names) ⇒ ::Array<Symbol>
Creates methods for reading and writing to a instance variable with
volatile (Java) semantic as attr_volatile does.
The instance variable should be accessed oly through generated methods.
This method generates following methods: value
, value=(new_value) #=> new_value
,
swap_value(new_value) #=> old_value
,
compare_and_set_value(expected, value) #=> true || false
, update_value(&block)
.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/concurrent-ruby/concurrent/synchronization/object.rb', line 116 def self.attr_atomic(*names) @__atomic_fields__ ||= [] @__atomic_fields__ += names safe_initialization! define_initialize_atomic_fields names.each do |name| ivar = :"@Atomic#{name.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }}" class_eval <<-RUBY, __FILE__, __LINE__ + 1 def #{name} #{ivar}.get end def #{name}=(value) #{ivar}.set value end def swap_#{name}(value) #{ivar}.swap value end def compare_and_set_#{name}(expected, value) #{ivar}.compare_and_set expected, value end def update_#{name}(&block) #{ivar}.update(&block) end RUBY end names.flat_map { |n| [n, :"#{n}=", :"swap_#{n}", :"compare_and_set_#{n}", :"update_#{n}"] } end |
.attr_volatile(*names) ⇒ ::Array<Symbol>
Creates methods for reading and writing (as attr_accessor
does) to a instance variable with
volatile (Java) semantic. The instance variable should be accessed only through generated methods.
|
# File 'lib/concurrent-ruby/concurrent/synchronization/object.rb', line 28
|
.ensure_safe_initialization_when_final_fields_are_present ⇒ true
For testing purposes, quite slow. Injects assert code to new method which will raise if class instance contains any instance variables with CamelCase names and isn't safe_initialization?.
77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/concurrent-ruby/concurrent/synchronization/object.rb', line 77 def self.ensure_safe_initialization_when_final_fields_are_present Object.class_eval do def self.new(*args, &block) object = super(*args, &block) ensure has_final_field = object.instance_variables.any? { |v| v.to_s =~ /^@[A-Z]/ } if has_final_field && !safe_initialization? raise "there was an instance of #{object.class} with final field but not marked with safe_initialization!" end end end true end |
.safe_initialization! ⇒ true
By calling this method on a class, it and all its children are marked to be constructed safely. Meaning that all writes (ivar initializations) are made visible to all readers of newly constructed object. It ensures same behaviour as Java's final fields.
53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/concurrent-ruby/concurrent/synchronization/object.rb', line 53 def self.safe_initialization! # define only once, and not again in children return if safe_initialization? # @!visibility private def self.new(*args, &block) object = super(*args, &block) ensure object. if object end @safe_initialization = true end |
.safe_initialization? ⇒ true, false
Returns if this class is safely initialized.
68 69 70 71 |
# File 'lib/concurrent-ruby/concurrent/synchronization/object.rb', line 68 def self.safe_initialization? @safe_initialization = false unless defined? @safe_initialization @safe_initialization || (superclass.respond_to?(:safe_initialization?) && superclass.safe_initialization?) end |