File tree Expand file tree Collapse file tree 2 files changed +45
-0
lines changed Expand file tree Collapse file tree 2 files changed +45
-0
lines changed Original file line number Diff line number Diff line change @@ -78,6 +78,23 @@ def take(timeout = nil)
78
78
end
79
79
end
80
80
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
+
81
98
# Put a value into an `MVar`, blocking if there is already a value until
82
99
# it is empty. A timeout can be set to limit the time spent blocked, in
83
100
# which case it returns `TIMEOUT` if the time is exceeded.
Original file line number Diff line number Diff line change @@ -70,6 +70,34 @@ def dereferenceable_subject(value, opts = {})
70
70
71
71
end
72
72
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
+
73
101
describe '#put' do
74
102
75
103
it 'sets the MVar to be empty' do
You can’t perform that action at this time.
0 commit comments