Skip to content

Commit f65bc44

Browse files
committed
IVar is now a Synchronization::Object.
* Dereferenceable supports injection of a mutex * Obligation supports injection of a mutex * IVar extends Synchronization::Object * IVar passes `self` to Obligation as injected mutex * IVar, Promise, and Future no longer call `mutex#lock`
1 parent ac51231 commit f65bc44

File tree

4 files changed

+37
-57
lines changed

4 files changed

+37
-57
lines changed

lib/concurrent/dereferenceable.rb

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,24 +39,17 @@ module Dereferenceable
3939
#
4040
# @return [Object] the current value of the object
4141
def value
42-
mutex.lock
43-
apply_deref_options(@value)
44-
ensure
45-
mutex.unlock
42+
mutex.synchronize { apply_deref_options(@value) }
4643
end
47-
4844
alias_method :deref, :value
4945

5046
protected
5147

5248
# Set the internal value of this object
5349
#
5450
# @param [Object] val the new value
55-
def value=(val)
56-
mutex.lock
57-
@value = val
58-
ensure
59-
mutex.unlock
51+
def value=(value)
52+
mutex.synchronize{ @value = value }
6053
end
6154

6255
# A mutex lock used for synchronizing thread-safe operations. Methods defined
@@ -74,8 +67,8 @@ def mutex
7467
# @note This method *must* be called from within the constructor of the including class.
7568
#
7669
# @see #mutex
77-
def init_mutex
78-
@mutex = Mutex.new
70+
def init_mutex(mutex = Mutex.new)
71+
@mutex = mutex
7972
end
8073

8174
# Set the options which define the operations #value performs before
@@ -91,14 +84,13 @@ def init_mutex
9184
# @option opts [String] :copy_on_deref (nil) call the given `Proc` passing
9285
# the internal value and returning the value returned from the proc
9386
def set_deref_options(opts = {})
94-
mutex.lock
95-
@dup_on_deref = opts[:dup_on_deref] || opts[:dup]
96-
@freeze_on_deref = opts[:freeze_on_deref] || opts[:freeze]
97-
@copy_on_deref = opts[:copy_on_deref] || opts[:copy]
98-
@do_nothing_on_deref = !(@dup_on_deref || @freeze_on_deref || @copy_on_deref)
99-
nil
100-
ensure
101-
mutex.unlock
87+
mutex.synchronize do
88+
@dup_on_deref = opts[:dup_on_deref] || opts[:dup]
89+
@freeze_on_deref = opts[:freeze_on_deref] || opts[:freeze]
90+
@copy_on_deref = opts[:copy_on_deref] || opts[:copy]
91+
@do_nothing_on_deref = !(@dup_on_deref || @freeze_on_deref || @copy_on_deref)
92+
nil
93+
end
10294
end
10395

10496
# @!visibility private

lib/concurrent/ivar.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require 'concurrent/errors'
44
require 'concurrent/obligation'
55
require 'concurrent/observable'
6+
require 'concurrent/synchronization'
67

78
module Concurrent
89

@@ -38,7 +39,7 @@ module Concurrent
3839
# ivar.set 14
3940
# ivar.get #=> 14
4041
# ivar.set 2 # would now be an error
41-
class IVar
42+
class IVar < Synchronization::Object
4243
include Obligation
4344
include Observable
4445

@@ -56,7 +57,8 @@ class IVar
5657
# @option opts [String] :copy_on_deref (nil) call the given `Proc` passing
5758
# the internal value and returning the value returned from the proc
5859
def initialize(value = NO_VALUE, opts = {})
59-
init_obligation
60+
super(&nil)
61+
init_obligation(self)
6062
self.observers = CopyOnWriteObserverSet.new
6163
set_deref_options(opts)
6264
@state = :pending

lib/concurrent/obligation.rb

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,7 @@ def value!(timeout = nil)
113113
#
114114
# @return [Symbol] the current state
115115
def state
116-
mutex.lock
117-
@state
118-
ensure
119-
mutex.unlock
116+
mutex.synchronize { @state }
120117
end
121118

122119
# If an exception was raised during processing this will return the
@@ -125,10 +122,7 @@ def state
125122
#
126123
# @return [Exception] the exception raised during processing or `nil`
127124
def reason
128-
mutex.lock
129-
@reason
130-
ensure
131-
mutex.unlock
125+
mutex.synchronize { @reason }
132126
end
133127

134128
# @example allows Obligation to be risen
@@ -147,8 +141,8 @@ def get_arguments_from(opts = {}) # :nodoc:
147141
end
148142

149143
# @!visibility private
150-
def init_obligation # :nodoc:
151-
init_mutex
144+
def init_obligation(*args) # :nodoc:
145+
init_mutex(*args)
152146
@event = Event.new
153147
end
154148

@@ -170,10 +164,7 @@ def set_state(success, value, reason) # :nodoc:
170164

171165
# @!visibility private
172166
def state=(value) # :nodoc:
173-
mutex.lock
174-
@state = value
175-
ensure
176-
mutex.unlock
167+
mutex.synchronize { @state = value }
177168
end
178169

179170
# Atomic compare and set operation
@@ -186,15 +177,14 @@ def state=(value) # :nodoc:
186177
#
187178
# @!visibility private
188179
def compare_and_set_state(next_state, expected_current) # :nodoc:
189-
mutex.lock
190-
if @state == expected_current
191-
@state = next_state
192-
true
193-
else
194-
false
180+
mutex.synchronize do
181+
if @state == expected_current
182+
@state = next_state
183+
true
184+
else
185+
false
186+
end
195187
end
196-
ensure
197-
mutex.unlock
198188
end
199189

200190
# executes the block within mutex if current state is included in expected_states
@@ -203,16 +193,15 @@ def compare_and_set_state(next_state, expected_current) # :nodoc:
203193
#
204194
# @!visibility private
205195
def if_state(*expected_states) # :nodoc:
206-
mutex.lock
207-
raise ArgumentError.new('no block given') unless block_given?
208-
209-
if expected_states.include? @state
210-
yield
211-
else
212-
false
196+
mutex.synchronize do
197+
raise ArgumentError.new('no block given') unless block_given?
198+
199+
if expected_states.include? @state
200+
yield
201+
else
202+
false
203+
end
213204
end
214-
ensure
215-
mutex.unlock
216205
end
217206
end
218207
end

lib/concurrent/promise.rb

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -481,10 +481,7 @@ def set_state!(success, value, reason)
481481

482482
# @!visibility private
483483
def synchronized_set_state!(success, value, reason)
484-
mutex.lock
485-
set_state!(success, value, reason)
486-
ensure
487-
mutex.unlock
484+
mutex.synchronize { set_state!(success, value, reason) }
488485
end
489486
end
490487
end

0 commit comments

Comments
 (0)