Skip to content

Commit 26b7a77

Browse files
committed
Merge pull request #449 from lionelperrin/master
MVar#take accepts a block as parameter
2 parents 9c5b03a + 38382b0 commit 26b7a77

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

lib/concurrent/mvar.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,23 @@ def take(timeout = nil)
7878
end
7979
end
8080

81+
# acquires lock on the from an `MVAR`, yields the value to provided block,
82+
# and release lock. A timeout can be set to limit the time spent blocked,
83+
# in which case it returns `TIMEOUT` if the time is exceeded.
84+
# @return [Object] the value returned by the block, or `TIMEOUT`
85+
def borrow(timeout = nil)
86+
@mutex.synchronize do
87+
wait_for_full(timeout)
88+
89+
# if we timeoud out we'll still be empty
90+
if unlocked_full?
91+
yield @value
92+
else
93+
TIMEOUT
94+
end
95+
end
96+
end
97+
8198
# Put a value into an `MVar`, blocking if there is already a value until
8299
# it is empty. A timeout can be set to limit the time spent blocked, in
83100
# which case it returns `TIMEOUT` if the time is exceeded.

spec/concurrent/mvar_spec.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,34 @@ def dereferenceable_subject(value, opts = {})
7070

7171
end
7272

73+
describe '#borrow' do
74+
75+
it 'yields current value to the block and puts back value' do
76+
m = MVar.new(14)
77+
expect { |b| m.borrow(&b) }.to yield_with_args(14)
78+
expect(m.take).to eq(14)
79+
end
80+
81+
it 'puts back value even if an exception is raised' do
82+
m = MVar.new(14)
83+
expect { m.borrow { fail 'boom!' } }.to raise_error('boom!')
84+
expect(m.take).to eq(14)
85+
end
86+
87+
it 'returns the returned value of the block' do
88+
m = MVar.new(14)
89+
expect(m.borrow{2}).to eq(2)
90+
expect(m.take).to eq(14)
91+
end
92+
93+
it 'returns TIMEOUT on timeout on an empty MVar' do
94+
m = MVar.new
95+
expect(m.borrow(0.1){}).to eq MVar::TIMEOUT
96+
end
97+
98+
end
99+
100+
73101
describe '#put' do
74102

75103
it 'sets the MVar to be empty' do

0 commit comments

Comments
 (0)