Skip to content

Commit 6f91c14

Browse files
committed
TVar: fix read-after-write within the same transaction and add specs for it.
1 parent 2784fe8 commit 6f91c14

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

lib/concurrent/tvar.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,13 @@ def initialize
163163

164164
def read(tvar)
165165
Concurrent::abort_transaction unless valid?
166-
@read_log.push(ReadLogEntry.new(tvar, tvar.unsafe_version))
167-
tvar.unsafe_value
166+
167+
if @write_log.has_key? tvar
168+
@write_log[tvar]
169+
else
170+
@read_log.push(ReadLogEntry.new(tvar, tvar.unsafe_version))
171+
tvar.unsafe_value
172+
end
168173
end
169174

170175
def write(tvar, value)

spec/concurrent/tvar_spec.rb

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,11 @@ module Concurrent
120120
end
121121
end
122122

123-
a.wait
124123
Concurrent::atomically do
124+
a.wait
125125
expect(t.value).to eq 0
126+
b.count_down
126127
end
127-
b.count_down
128128
end
129129

130130
it 'provides strong isolation' do
@@ -147,11 +147,37 @@ module Concurrent
147147
end
148148

149149
it 'nests' do
150+
t = TVar.new(0)
151+
150152
Concurrent::atomically do
153+
expect(t.value).to eq 0
154+
t.value = 1
151155
Concurrent::atomically do
156+
expect(t.value).to eq 1
157+
t.value = 2
152158
Concurrent::atomically do
159+
expect(t.value).to eq 2
160+
t.value = 3
153161
end
162+
expect(t.value).to eq 3
163+
t.value = 4
154164
end
165+
expect(t.value).to eq 4
166+
t.value = 5
167+
end
168+
169+
expect(t.value).to eq 5
170+
end
171+
172+
it 'reflects transactional writes from within the same transaction' do
173+
t = TVar.new(0)
174+
175+
Concurrent::atomically do
176+
expect(t.value).to eq 0
177+
t.value = 14
178+
expect(t.value).to eq 14
179+
t.value = 2
180+
expect(t.value).to eq 2
155181
end
156182
end
157183

0 commit comments

Comments
 (0)