File tree Expand file tree Collapse file tree 2 files changed +19
-78
lines changed
Expand file tree Collapse file tree 2 files changed +19
-78
lines changed Original file line number Diff line number Diff line change 11module Concurrent
22 class Exchanger
33
4- def initialize
5- @mutex = Mutex . new
6- @condition = Condition . new
7- @slot = new_slot
4+ EMPTY = Object . new
5+
6+ def initialize ( opts = { } )
7+ @first = MVar . new ( EMPTY , opts )
8+ @second = MVar . new ( MVar ::EMPTY , opts )
89 end
910
1011 def exchange ( value , timeout = nil )
11- @mutex . synchronize do
12-
13- replace_slot_if_fulfilled
14-
15- slot = @slot
16-
17- if slot . state == :empty
18- slot . value_1 = value
19- slot . state = :waiting
20- wait_for_value ( slot , timeout )
21- slot . value_2
12+ first = @first . take ( timeout )
13+ if first == MVar ::TIMEOUT
14+ nil
15+ elsif first == EMPTY
16+ @first . put value
17+ second = @second . take timeout
18+ if second == MVar ::TIMEOUT
19+ nil
2220 else
23- slot . value_2 = value
24- slot . state = :fulfilled
25- @condition . broadcast
26- slot . value_1
21+ second
2722 end
28-
23+ else
24+ @first . put EMPTY
25+ @second . put value
26+ first
2927 end
3028 end
3129
32- Slot = Struct . new ( :value_1 , :value_2 , :state )
33-
34- private_constant :Slot
35-
36- private
37-
38- def replace_slot_if_fulfilled
39- @slot = new_slot if @slot . state == :fulfilled
40- end
41-
42- def wait_for_value ( slot , timeout )
43- remaining = Condition ::Result . new ( timeout )
44- while slot . state == :waiting && remaining . can_wait?
45- remaining = @condition . wait ( @mutex , remaining . remaining_time )
46- end
47- end
48-
49- def new_slot
50- Slot . new ( nil , nil , :empty )
51- end
52-
5330 end
54- end
31+ end
Original file line number Diff line number Diff line change @@ -62,41 +62,5 @@ module Concurrent
6262 end
6363 end
6464 end
65-
66- context 'spurious wake ups' do
67-
68- before ( :each ) do
69- def subject . simulate_spurious_wake_up
70- @mutex . synchronize do
71- @condition . broadcast
72- end
73- end
74- end
75-
76- it 'should resist to spurious wake ups without timeout' do
77- @expected = false
78- Thread . new { exchanger . exchange ( 1 ) ; @expected = true }
79-
80- sleep ( 0.1 )
81- subject . simulate_spurious_wake_up
82-
83- sleep ( 0.1 )
84- @expected . should be_false
85- end
86-
87- it 'should resist to spurious wake ups with timeout' do
88- @expected = false
89- Thread . new { exchanger . exchange ( 1 , 0.3 ) ; @expected = true }
90-
91- sleep ( 0.1 )
92- subject . simulate_spurious_wake_up
93-
94- sleep ( 0.1 )
95- @expected . should be_false
96-
97- sleep ( 0.2 )
98- @expected . should be_true
99- end
100- end
10165 end
10266end
You can’t perform that action at this time.
0 commit comments