11module Concurrent
22 module Synchronization
33
4- # Safe synchronization under any Ruby implementation.
5- # It provides methods like {#synchronize}, {#ns_wait}, {#ns_signal} and {#ns_broadcast}.
6- # Provides a single layer which can improve its implementation over time without changes needed to
7- # the classes using it. Use {Synchronization::Object} not this abstract class.
8- #
9- # @note this object does not support usage together with
10- # [`Thread#wakeup`](http://ruby-doc.org/core-2.2.0/Thread.html#method-i-wakeup)
11- # and [`Thread#raise`](http://ruby-doc.org/core-2.2.0/Thread.html#method-i-raise).
12- # `Thread#sleep` and `Thread#wakeup` will work as expected but mixing `Synchronization::Object#wait` and
13- # `Thread#wakeup` will not work on all platforms.
14- #
15- # @see {Event} implementation as an example of this class use
16- #
17- # @example simple
18- # class AnClass < Synchronization::Object
19- # def initialize
20- # super
21- # synchronize { @value = 'asd' }
22- # end
23- #
24- # def value
25- # synchronize { @value }
26- # end
27- # end
28- #
29- # @api private
4+ # @!macro synchronization_object
5+ # @!visibility private
306 class AbstractObject
317
32- # @abstract for helper ivar initialization if needed,
33- # otherwise it can be left empty. It has to call ns_initialize.
34- def initialize
8+ # @!macro [attach] synchronization_object_method_initialize
9+ #
10+ # @abstract for helper ivar initialization if needed,
11+ # otherwise it can be left empty. It has to call ns_initialize.
12+ def initialize ( *args , &block )
3513 raise NotImplementedError
3614 end
3715
3816 protected
3917
40- # @yield runs the block synchronized against this object,
41- # equivalent of java's `synchronize(this) {}`
42- # @note can by made public in descendants if required by `public :synchronize`
18+ # @!macro [attach] synchronization_object_method_synchronize
19+ #
20+ # @yield runs the block synchronized against this object,
21+ # equivalent of java's `synchronize(this) {}`
22+ # @note can by made public in descendants if required by `public :synchronize`
4323 def synchronize
4424 raise NotImplementedError
4525 end
4626
47- # initialization of the object called inside synchronize block
48- # @note has to be called manually when required in children of this class
49- # @example
50- # class Child < Concurrent::Synchornization::Object
51- # def initialize(*args, &block)
52- # super(&nil)
53- # synchronize { ns_initialize(*args, &block) }
27+ # @!macro [attach] synchronization_object_method_ns_initialize
28+ #
29+ # initialization of the object called inside synchronize block
30+ # @note has to be called manually when required in children of this class
31+ # @example
32+ # class Child < Concurrent::Synchornization::Object
33+ # def initialize(*args, &block)
34+ # super(&nil)
35+ # synchronize { ns_initialize(*args, &block) }
36+ # end
37+ #
38+ # def ns_initialize(*args, &block)
39+ # @args = args
40+ # end
5441 # end
55- #
56- # def ns_initialize(*args, &block)
57- # @args = args
58- # end
59- # end
6042 def ns_initialize ( *args , &block )
6143 end
6244
63- # Wait until condition is met or timeout passes,
64- # protects against spurious wake-ups.
65- # @param [Numeric, nil] timeout in seconds, `nil` means no timeout
66- # @yield condition to be met
67- # @yieldreturn [true, false]
68- # @return [true, false] if condition met
69- # @note only to be used inside synchronized block
70- # @note to provide direct access to this method in a descendant add method
71- # ```
72- # def wait_until(timeout = nil, &condition)
73- # synchronize { ns_wait_until(timeout, &condition) }
74- # end
75- # ```
45+ # @!macro [attach] synchronization_object_method_ns_wait_until
46+ #
47+ # Wait until condition is met or timeout passes,
48+ # protects against spurious wake-ups.
49+ # @param [Numeric, nil] timeout in seconds, `nil` means no timeout
50+ # @yield condition to be met
51+ # @yieldreturn [true, false]
52+ # @return [true, false] if condition met
53+ # @note only to be used inside synchronized block
54+ # @note to provide direct access to this method in a descendant add method
55+ # ```
56+ # def wait_until(timeout = nil, &condition)
57+ # synchronize { ns_wait_until(timeout, &condition) }
58+ # end
59+ # ```
7660 def ns_wait_until ( timeout = nil , &condition )
7761 if timeout
7862 wait_until = Concurrent . monotonic_time + timeout
@@ -90,65 +74,75 @@ def ns_wait_until(timeout = nil, &condition)
9074 end
9175 end
9276
93- # Wait until another thread calls #signal or #broadcast,
94- # spurious wake-ups can happen.
95- #
96- # @param [Numeric, nil] timeout in seconds, `nil` means no timeout
97- # @return [self]
98- # @note only to be used inside synchronized block
99- # @note to provide direct access to this method in a descendant add method
100- # ```
101- # def wait(timeout = nil)
102- # synchronize { ns_wait(timeout) }
103- # end
104- # ```
77+ # @!macro [attach] synchronization_object_method_ns_wait
78+ #
79+ # Wait until another thread calls #signal or #broadcast,
80+ # spurious wake-ups can happen.
81+ #
82+ # @param [Numeric, nil] timeout in seconds, `nil` means no timeout
83+ # @return [self]
84+ # @note only to be used inside synchronized block
85+ # @note to provide direct access to this method in a descendant add method
86+ # ```
87+ # def wait(timeout = nil)
88+ # synchronize { ns_wait(timeout) }
89+ # end
90+ # ```
10591 def ns_wait ( timeout = nil )
10692 raise NotImplementedError
10793 end
10894
109- # Signal one waiting thread.
110- # @return [self]
111- # @note only to be used inside synchronized block
112- # @note to provide direct access to this method in a descendant add method
113- # ```
114- # def signal
115- # synchronize { ns_signal }
116- # end
117- # ```
95+ # @!macro [attach] synchronization_object_method_ns_signal
96+ #
97+ # Signal one waiting thread.
98+ # @return [self]
99+ # @note only to be used inside synchronized block
100+ # @note to provide direct access to this method in a descendant add method
101+ # ```
102+ # def signal
103+ # synchronize { ns_signal }
104+ # end
105+ # ```
118106 def ns_signal
119107 raise NotImplementedError
120108 end
121109
122- # Broadcast to all waiting threads.
123- # @return [self]
124- # @note only to be used inside synchronized block
125- # @note to provide direct access to this method in a descendant add method
126- # ```
127- # def broadcast
128- # synchronize { ns_broadcast }
129- # end
130- # ```
110+ # @!macro [attach] synchronization_object_method_ns_broadcast
111+ #
112+ # Broadcast to all waiting threads.
113+ # @return [self]
114+ # @note only to be used inside synchronized block
115+ # @note to provide direct access to this method in a descendant add method
116+ # ```
117+ # def broadcast
118+ # synchronize { ns_broadcast }
119+ # end
120+ # ```
131121 def ns_broadcast
132122 raise NotImplementedError
133123 end
134124
135- # Allows to construct immutable objects where all fields are visible after initialization, not requiring
136- # further synchronization on access.
137- # @example
138- # class AClass
139- # attr_reader :val
140- # def initialize(val)
141- # @val = val # final value, after assignment it's not changed (just convention, not enforced)
142- # ensure_ivar_visibility!
143- # # now it can be shared as Java's final field
125+ # @!macro [attach] synchronization_object_method_ensure_ivar_visibility
126+ #
127+ # Allows to construct immutable objects where all fields are visible after initialization, not requiring
128+ # further synchronization on access.
129+ # @example
130+ # class AClass
131+ # attr_reader :val
132+ # def initialize(val)
133+ # @val = val # final value, after assignment it's not changed (just convention, not enforced)
134+ # ensure_ivar_visibility!
135+ # # now it can be shared as Java's final field
136+ # end
144137 # end
145- # end
146138 def ensure_ivar_visibility!
147139 raise NotImplementedError
148140 end
149141
150- # creates methods for reading and writing to a instance variable with volatile (Java semantic) instance variable
151- # return [Array<Symbol>] names of defined method names
142+ # @!macro [attach] synchronization_object_method_self_attr_volatile
143+ #
144+ # creates methods for reading and writing to a instance variable with volatile (Java semantic) instance variable
145+ # return [Array<Symbol>] names of defined method names
152146 def self . attr_volatile ( *names )
153147 names . each do |name |
154148 ivar = :"@volatile_#{ name } "
0 commit comments