Skip to content

Commit 219d39d

Browse files
committed
Fix CountDownLatch and Exchanger on JRuby
* make the threads sleep * allow the threads to be unblocked and killed
1 parent ea48751 commit 219d39d

File tree

5 files changed

+23
-13
lines changed

5 files changed

+23
-13
lines changed

lib/concurrent/atomic/java_count_down_latch.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ def initialize(count = 1)
1818
# @!macro count_down_latch_method_wait
1919
def wait(timeout = nil)
2020
if timeout.nil?
21-
@latch.await
21+
Synchronization::JRuby.sleep_interruptibly { @latch.await }
2222
true
2323
else
24-
@latch.await(1000 * timeout, java.util.concurrent.TimeUnit::MILLISECONDS)
24+
Synchronization::JRuby.sleep_interruptibly do
25+
@latch.await(1000 * timeout, java.util.concurrent.TimeUnit::MILLISECONDS)
26+
end
2527
end
2628
end
2729

lib/concurrent/exchanger.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,9 +315,11 @@ def initialize
315315
# @return [Object, CANCEL] the value exchanged by the other thread; {CANCEL} on timeout
316316
def do_exchange(value, timeout)
317317
if timeout.nil?
318-
@exchanger.exchange(value)
318+
Synchronization::JRuby.sleep_interruptibly { @exchanger.exchange(value) }
319319
else
320-
@exchanger.exchange(value, 1000 * timeout, java.util.concurrent.TimeUnit::MILLISECONDS)
320+
Synchronization::JRuby.sleep_interruptibly do
321+
@exchanger.exchange(value, 1000 * timeout, java.util.concurrent.TimeUnit::MILLISECONDS)
322+
end
321323
end
322324
rescue java.util.concurrent.TimeoutException
323325
CANCEL

spec/concurrent/atomic/count_down_latch_spec.rb

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,14 @@
4242

4343
describe '#wait' do
4444

45-
it 'blocks indefinitely' do
46-
# test the thread is kill-able
47-
in_thread(latch) { |l| l.wait }
48-
sleep 0.1
45+
it 'blocks indefinitely, and is kill-able' do
46+
t = in_thread(latch) { |l| l.wait }
47+
is_sleeping t
48+
end
49+
50+
it 'blocks indefinitely with timeout, and is kill-able' do
51+
t = in_thread(latch) { |l| l.wait 100 }
52+
is_sleeping t
4953
end
5054

5155
context 'count set to zero' do

spec/concurrent/exchanger_spec.rb

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,13 @@
88
latch_1 = Concurrent::CountDownLatch.new
99
latch_2 = Concurrent::CountDownLatch.new
1010

11-
in_thread do
11+
t = in_thread do
1212
latch_1.count_down
13-
subject.send(method_name, 1)
13+
subject.send(method_name, 0.1)
1414
latch_2.count_down
1515
end
1616

17-
latch_1.wait(1)
18-
latch_2.wait(0.1)
17+
is_sleeping t
1918
expect(latch_1.count).to eq 0
2019
expect(latch_2.count).to eq 1
2120
end
@@ -238,7 +237,6 @@ module Concurrent
238237
end
239238

240239
if defined? JavaExchanger
241-
242240
RSpec.describe JavaExchanger do
243241
it_behaves_like :exchanger
244242
end

spec/support/example_group_extensions.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ def in_thread(*args, &block)
3636
new_thread
3737
end
3838

39+
def is_sleeping(thread)
40+
expect(in_thread { Thread.pass until thread.status == 'sleep' }.join(1)).not_to eq nil
41+
end
42+
3943
def join_with(threads, timeout = 5)
4044
threads = Array(threads)
4145
threads.each do |t|

0 commit comments

Comments
 (0)