1
1
module Concurrent
2
2
module Synchronization
3
3
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
30
6
class AbstractObject
31
7
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 )
35
13
raise NotImplementedError
36
14
end
37
15
38
16
protected
39
17
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`
43
23
def synchronize
44
24
raise NotImplementedError
45
25
end
46
26
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
54
41
# end
55
- #
56
- # def ns_initialize(*args, &block)
57
- # @args = args
58
- # end
59
- # end
60
42
def ns_initialize ( *args , &block )
61
43
end
62
44
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
+ # ```
76
60
def ns_wait_until ( timeout = nil , &condition )
77
61
if timeout
78
62
wait_until = Concurrent . monotonic_time + timeout
@@ -90,65 +74,75 @@ def ns_wait_until(timeout = nil, &condition)
90
74
end
91
75
end
92
76
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
+ # ```
105
91
def ns_wait ( timeout = nil )
106
92
raise NotImplementedError
107
93
end
108
94
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
+ # ```
118
106
def ns_signal
119
107
raise NotImplementedError
120
108
end
121
109
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
+ # ```
131
121
def ns_broadcast
132
122
raise NotImplementedError
133
123
end
134
124
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
144
137
# end
145
- # end
146
138
def ensure_ivar_visibility!
147
139
raise NotImplementedError
148
140
end
149
141
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
152
146
def self . attr_volatile ( *names )
153
147
names . each do |name |
154
148
ivar = :"@volatile_#{ name } "
0 commit comments