Skip to content

Commit c690eb7

Browse files
committed
Merge pull request #462 from ruby-concurrency/sync-updates
Sync updates
2 parents 9f58449 + f465e95 commit c690eb7

File tree

13 files changed

+51
-54
lines changed

13 files changed

+51
-54
lines changed

examples/go-by-example-channels/non-blocking-channel-operations.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
s.default { print "no message received\n" }
1616
end
1717

18-
msg = 'hi'
18+
message = 'hi'
1919
Channel.select do |s|
20-
s.put(messages, msg) { |m| print "sent message #{m}\n" }
20+
s.put(messages, message) { |msg| print "sent message #{msg}\n" }
2121
s.default { print "no message sent\n" }
2222
end
2323

lib/concurrent/channel/tick.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
require 'concurrent/synchronization'
12
require 'concurrent/utility/monotonic_time'
23

34
module Concurrent
@@ -13,8 +14,9 @@ class Channel
1314
# @see Concurrent.monotonic_time
1415
# @see Concurrent::Channel.ticker
1516
# @see Concurrent::Channel.timer
16-
class Tick
17+
class Tick < Synchronization::Object
1718
include Comparable
19+
safe_initialization!
1820

1921
STRING_FORMAT = '%F %T.%6N %z %Z'.freeze
2022

lib/concurrent/concern/dereferenceable.rb

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,17 @@ module Concern
99
#
1010
# @!macro copy_options
1111
module Dereferenceable
12+
# NOTE: This module is going away in 2.0. In the mean time we need it to
13+
# play nicely with the synchronization layer. This means that the
14+
# including class SHOULD be synchronized and it MUST implement a
15+
# `#synchronize` method. Not doing so will lead to runtime errors.
1216

1317
# Return the value this object represents after applying the options specified
1418
# by the `#set_deref_options` method.
1519
#
1620
# @return [Object] the current value of the object
1721
def value
18-
mutex.synchronize { apply_deref_options(@value) }
22+
synchronize { apply_deref_options(@value) }
1923
end
2024
alias_method :deref, :value
2125

@@ -25,43 +29,24 @@ def value
2529
#
2630
# @param [Object] value the new value
2731
def value=(value)
28-
mutex.synchronize{ @value = value }
29-
end
30-
31-
# A mutex lock used for synchronizing thread-safe operations. Methods defined
32-
# by `Dereferenceable` are synchronized using the `Mutex` returned from this
33-
# method. Operations performed by the including class that operate on the
34-
# `@value` instance variable should be locked with this `Mutex`.
35-
#
36-
# @return [Mutex] the synchronization object
37-
def mutex
38-
@mutex
39-
end
40-
41-
# Initializes the internal `Mutex`.
42-
#
43-
# @note This method *must* be called from within the constructor of the including class.
44-
#
45-
# @see #mutex
46-
def init_mutex(mutex = Mutex.new)
47-
@mutex = mutex
32+
synchronize{ @value = value }
4833
end
4934

5035
# @!macro [attach] dereferenceable_set_deref_options
5136
# Set the options which define the operations #value performs before
5237
# returning data to the caller (dereferencing).
53-
#
38+
#
5439
# @note Most classes that include this module will call `#set_deref_options`
5540
# from within the constructor, thus allowing these options to be set at
5641
# object creation.
57-
#
42+
#
5843
# @param [Hash] opts the options defining dereference behavior.
5944
# @option opts [String] :dup_on_deref (false) call `#dup` before returning the data
6045
# @option opts [String] :freeze_on_deref (false) call `#freeze` before returning the data
6146
# @option opts [String] :copy_on_deref (nil) call the given `Proc` passing
6247
# the internal value and returning the value returned from the proc
6348
def set_deref_options(opts = {})
64-
mutex.synchronize{ ns_set_deref_options(opts) }
49+
synchronize{ ns_set_deref_options(opts) }
6550
end
6651

6752
# @!macro dereferenceable_set_deref_options

lib/concurrent/concern/obligation.rb

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ module Concern
99

1010
module Obligation
1111
include Concern::Dereferenceable
12+
# NOTE: The Dereferenceable module is going away in 2.0. In the mean time
13+
# we need it to place nicely with the synchronization layer. This means
14+
# that the including class SHOULD be synchronized and it MUST implement a
15+
# `#synchronize` method. Not doing so will lead to runtime errors.
1216

1317
# Has the obligation been fulfilled?
1418
#
@@ -104,7 +108,7 @@ def value!(timeout = nil)
104108
#
105109
# @return [Symbol] the current state
106110
def state
107-
mutex.synchronize { @state }
111+
synchronize { @state }
108112
end
109113

110114
# If an exception was raised during processing this will return the
@@ -113,7 +117,7 @@ def state
113117
#
114118
# @return [Exception] the exception raised during processing or `nil`
115119
def reason
116-
mutex.synchronize { @reason }
120+
synchronize { @reason }
117121
end
118122

119123
# @example allows Obligation to be risen
@@ -132,8 +136,7 @@ def get_arguments_from(opts = {})
132136
end
133137

134138
# @!visibility private
135-
def init_obligation(*args)
136-
init_mutex(*args)
139+
def init_obligation
137140
@event = Event.new
138141
end
139142

@@ -155,20 +158,20 @@ def set_state(success, value, reason)
155158

156159
# @!visibility private
157160
def state=(value)
158-
mutex.synchronize { ns_set_state(value) }
161+
synchronize { ns_set_state(value) }
159162
end
160163

161164
# Atomic compare and set operation
162165
# State is set to `next_state` only if `current state == expected_current`.
163166
#
164167
# @param [Symbol] next_state
165168
# @param [Symbol] expected_current
166-
#
169+
#
167170
# @return [Boolean] true is state is changed, false otherwise
168171
#
169172
# @!visibility private
170173
def compare_and_set_state(next_state, *expected_current)
171-
mutex.synchronize do
174+
synchronize do
172175
if expected_current.include? @state
173176
@state = next_state
174177
true
@@ -184,7 +187,7 @@ def compare_and_set_state(next_state, *expected_current)
184187
#
185188
# @!visibility private
186189
def if_state(*expected_states)
187-
mutex.synchronize do
190+
synchronize do
188191
raise ArgumentError.new('no block given') unless block_given?
189192

190193
if expected_states.include? @state

lib/concurrent/delay.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ def reconfigure(&block)
155155
protected
156156

157157
def ns_initialize(opts, &block)
158-
init_obligation(self)
158+
init_obligation
159159
set_deref_options(opts)
160160
@executor = opts[:executor]
161161

lib/concurrent/edge/future.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def post_on(executor, *args, &job)
131131
# Represents an event which will happen in future (will be completed). It has to always happen.
132132
class Event < Synchronization::LockableObject
133133
safe_initialization!
134-
private *attr_volatile_with_cas(:internal_state)
134+
private(*attr_volatile_with_cas(:internal_state))
135135
public :internal_state
136136
include Concern::Deprecation
137137
include Concern::Logging

lib/concurrent/ivar.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def try_set(value = NULL, &block)
153153
# @!visibility private
154154
def ns_initialize(value, opts)
155155
value = yield if block_given?
156-
init_obligation(self)
156+
init_obligation
157157
self.observers = Collection::CopyOnWriteObserverSet.new
158158
set_deref_options(opts)
159159

lib/concurrent/lazy_register.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ module Concurrent
1818
# @!macro edge_warning
1919
class LazyRegister < Synchronization::Object
2020

21-
private *attr_volatile_with_cas(:data)
21+
private(*attr_volatile_with_cas(:data))
2222

2323
def initialize
2424
super

lib/concurrent/maybe.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
require 'concurrent/synchronization'
2+
13
module Concurrent
24

35
# A `Maybe` encapsulates an optional value. A `Maybe` either contains a value
@@ -99,8 +101,9 @@ module Concurrent
99101
#
100102
# @see https://hackage.haskell.org/package/base-4.2.0.1/docs/Data-Maybe.html Haskell Data.Maybe
101103
# @see https://github.com/purescript/purescript-maybe/blob/master/docs/Data.Maybe.md PureScript Data.Maybe
102-
class Maybe
104+
class Maybe < Synchronization::Object
103105
include Comparable
106+
safe_initialization!
104107

105108
# Indicates that the given attribute has not been set.
106109
# When `Just` the {#nothing} getter will return `NONE`.
@@ -168,15 +171,15 @@ def self.nothing(error = '')
168171
end
169172

170173
# Is this `Maybe` a `Just` (successfully fulfilled with a value)?
171-
#
174+
#
172175
# @return [Boolean] True if `Just` or false if `Nothing`.
173176
def just?
174177
! nothing?
175178
end
176179
alias :fulfilled? :just?
177180

178181
# Is this `Maybe` a `nothing` (rejected with an exception upon fulfillment)?
179-
#
182+
#
180183
# @return [Boolean] True if `Nothing` or false if `Just`.
181184
def nothing?
182185
@nothing != NONE

lib/concurrent/mvar.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require 'concurrent/concern/dereferenceable'
2+
require 'concurrent/synchronization'
23

34
module Concurrent
45

@@ -34,9 +35,9 @@ module Concurrent
3435
# 2. S. Peyton Jones, A. Gordon, and S. Finne. [Concurrent Haskell](http://dl.acm.org/citation.cfm?id=237794).
3536
# In Proceedings of the 23rd Symposium on Principles of Programming Languages
3637
# (PoPL), 1996.
37-
class MVar
38-
38+
class MVar < Synchronization::Object
3939
include Concern::Dereferenceable
40+
safe_initialization!
4041

4142
# Unique value that represents that an `MVar` was empty
4243
EMPTY = Object.new
@@ -200,6 +201,12 @@ def full?
200201
!empty?
201202
end
202203

204+
protected
205+
206+
def synchronize(&block)
207+
@mutex.synchronize(&block)
208+
end
209+
203210
private
204211

205212
def unlocked_empty?

0 commit comments

Comments
 (0)