Skip to content

Commit b342abc

Browse files
committed
Better documentation of Synchronization classes.
1 parent 251a32f commit b342abc

File tree

7 files changed

+158
-106
lines changed

7 files changed

+158
-106
lines changed

lib/concurrent/synchronization/abstract_object.rb

Lines changed: 93 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,62 @@
11
module 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}"

lib/concurrent/synchronization/abstract_struct.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module Concurrent
22
module Synchronization
33

44
# @!visibility private
5-
# @api private
5+
# @!macro internal_implementation_note
66
module AbstractStruct
77

88
# @!visibility private

lib/concurrent/synchronization/java_object.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ module Synchronization
66
if Concurrent.on_jruby?
77
require 'jruby'
88

9-
# @api private
9+
# @!visibility private
10+
# @!macro internal_implementation_note
1011
class JavaObject < AbstractObject
1112

1213
def self.attr_volatile(*names)

lib/concurrent/synchronization/monitor_object.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
module Concurrent
22
module Synchronization
33

4-
# @api private
4+
# @!visibility private
5+
# @!macro internal_implementation_note
56
class MonitorObject < MutexObject
67
def initialize
78
@__lock__ = ::Monitor.new

lib/concurrent/synchronization/mutex_object.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
module Concurrent
22
module Synchronization
33

4-
# @api private
4+
# @!visibility private
5+
# @!macro internal_implementation_note
56
class MutexObject < AbstractObject
67
def initialize
78
@__lock__ = ::Mutex.new

lib/concurrent/synchronization/object.rb

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
module Concurrent
22
module Synchronization
33

4-
# @api private
4+
# @!visibility private
5+
# @!macro internal_implementation_note
56
Implementation = case
67
when Concurrent.on_jruby?
78
JavaObject
@@ -17,8 +18,61 @@ module Synchronization
1718
end
1819
private_constant :Implementation
1920

20-
# @see AbstractObject AbstractObject which defines interface of this class.
21+
# @!macro [attach] synchronization_object
22+
#
23+
# Safe synchronization under any Ruby implementation.
24+
# It provides methods like {#synchronize}, {#wait}, {#signal} and {#broadcast}.
25+
# Provides a single layer which can improve its implementation over time without changes needed to
26+
# the classes using it. Use {Synchronization::Object} not this abstract class.
27+
#
28+
# @note this object does not support usage together with
29+
# [`Thread#wakeup`](http://ruby-doc.org/core-2.2.0/Thread.html#method-i-wakeup)
30+
# and [`Thread#raise`](http://ruby-doc.org/core-2.2.0/Thread.html#method-i-raise).
31+
# `Thread#sleep` and `Thread#wakeup` will work as expected but mixing `Synchronization::Object#wait` and
32+
# `Thread#wakeup` will not work on all platforms.
33+
#
34+
# @see {Event} implementation as an example of this class use
35+
#
36+
# @example simple
37+
# class AnClass < Synchronization::Object
38+
# def initialize
39+
# super
40+
# synchronize { @value = 'asd' }
41+
# end
42+
#
43+
# def value
44+
# synchronize { @value }
45+
# end
46+
# end
47+
#
2148
class Object < Implementation
49+
50+
# @!method initialize(*args, &block)
51+
# @!macro synchronization_object_method_initialize
52+
53+
# @!method synchronize
54+
# @!macro synchronization_object_method_synchronize
55+
56+
# @!method initialize(*args, &block)
57+
# @!macro synchronization_object_method_ns_initialize
58+
59+
# @!method wait_until(timeout = nil, &condition)
60+
# @!macro synchronization_object_method_ns_wait_until
61+
62+
# @!method wait(timeout = nil)
63+
# @!macro synchronization_object_method_ns_wait
64+
65+
# @!method signal
66+
# @!macro synchronization_object_method_ns_signal
67+
68+
# @!method broadcast
69+
# @!macro synchronization_object_method_ns_broadcast
70+
71+
# @!method ensure_ivar_visibility!
72+
# @!macro synchronization_object_method_ensure_ivar_visibility
73+
74+
# @!method self.attr_volatile(*names)
75+
# @!macro synchronization_object_method_self_attr_volatile
2276
end
2377
end
2478
end

lib/concurrent/synchronization/rbx_object.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ module Synchronization
33

44
if Concurrent.on_rbx?
55

6-
# @api private
6+
# @!visibility private
7+
# @!macro internal_implementation_note
78
class RbxObject < AbstractObject
89
def initialize
910
@Waiters = []

0 commit comments

Comments
 (0)