Skip to content

Commit 9841679

Browse files
authored
GC safepoints and @preserve for read and write (#119)
* Add GC safepoints on read and write * Another safepoint * Move safepoint from flushbuffer to writedata! * GC safety
1 parent 7a81acc commit 9841679

File tree

2 files changed

+16
-12
lines changed

2 files changed

+16
-12
lines changed

src/buffer.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ end
187187
# Copy data from `data` to `buf`.
188188
function copydata!(buf::Buffer, data::Ptr{UInt8}, nbytes::Integer)
189189
makemargin!(buf, nbytes)
190-
unsafe_copyto!(marginptr(buf), data, nbytes)
190+
GC.@preserve buf unsafe_copyto!(marginptr(buf), data, nbytes)
191191
supplied!(buf, nbytes)
192192
return buf
193193
end
@@ -197,7 +197,7 @@ function copydata!(data::Ptr{UInt8}, buf::Buffer, nbytes::Integer)
197197
# NOTE: It's caller's responsibility to ensure that the buffer has at least
198198
# nbytes.
199199
@assert buffersize(buf) nbytes
200-
unsafe_copyto!(data, bufferptr(buf), nbytes)
200+
GC.@preserve buf unsafe_copyto!(data, bufferptr(buf), nbytes)
201201
consumed!(buf, nbytes)
202202
return data
203203
end
@@ -206,14 +206,14 @@ end
206206
function insertdata!(buf::Buffer, data::Ptr{UInt8}, nbytes::Integer)
207207
makemargin!(buf, nbytes)
208208
copyto!(buf.data, buf.bufferpos + nbytes, buf.data, buf.bufferpos, buffersize(buf))
209-
unsafe_copyto!(bufferptr(buf), data, nbytes)
209+
GC.@preserve buf unsafe_copyto!(bufferptr(buf), data, nbytes)
210210
supplied!(buf, nbytes)
211211
return buf
212212
end
213213

214214
# Find the first occurrence of a specific byte.
215215
function findbyte(buf::Buffer, byte::UInt8)
216-
p = ccall(
216+
p = GC.@preserve buf ccall(
217217
:memchr,
218218
Ptr{UInt8},
219219
(Ptr{UInt8}, Cint, Csize_t),

src/stream.jl

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ function Base.readuntil(stream::TranscodingStream, delim::UInt8; keep::Bool=fals
334334
@assert filled == 0
335335
ret = Vector{UInt8}(undef, sz)
336336
end
337-
copydata!(pointer(ret, filled+1), buffer1, sz)
337+
GC.@preserve ret copydata!(pointer(ret, filled+1), buffer1, sz)
338338
filled += sz
339339
if found
340340
if !keep
@@ -360,6 +360,7 @@ function Base.unsafe_read(stream::TranscodingStream, output::Ptr{UInt8}, nbytes:
360360
m = min(buffersize(buffer), p_end - p)
361361
copydata!(p, buffer, m)
362362
p += m
363+
GC.safepoint()
363364
end
364365
if p < p_end && eof(stream)
365366
throw(EOFError())
@@ -376,7 +377,7 @@ function Base.readbytes!(stream::TranscodingStream, b::AbstractArray{UInt8}, nb=
376377
resize!(b, min(length(b) * 2, nb))
377378
resized = true
378379
end
379-
filled += unsafe_read(stream, pointer(b, filled+1), min(length(b), nb)-filled)
380+
filled += GC.@preserve b unsafe_read(stream, pointer(b, filled+1), min(length(b), nb)-filled)
380381
end
381382
if resized
382383
resize!(b, filled)
@@ -392,7 +393,7 @@ end
392393
function Base.readavailable(stream::TranscodingStream)
393394
n = bytesavailable(stream)
394395
data = Vector{UInt8}(undef, n)
395-
unsafe_read(stream, pointer(data), n)
396+
GC.@preserve data unsafe_read(stream, pointer(data), n)
396397
return data
397398
end
398399

@@ -405,7 +406,7 @@ The next `read(stream, sizeof(data))` call will read data that are just
405406
inserted.
406407
"""
407408
function unread(stream::TranscodingStream, data::ByteData)
408-
unsafe_unread(stream, pointer(data), sizeof(data))
409+
GC.@preserve data unsafe_unread(stream, pointer(data), sizeof(data))
409410
end
410411

411412
"""
@@ -462,6 +463,7 @@ function Base.unsafe_write(stream::TranscodingStream, input::Ptr{UInt8}, nbytes:
462463
m = min(marginsize(buffer1), p_end - p)
463464
copydata!(buffer1, p, m)
464465
p += m
466+
GC.safepoint()
465467
end
466468
return Int(p - input)
467469
end
@@ -636,8 +638,8 @@ end
636638
function callprocess(stream::TranscodingStream, inbuf::Buffer, outbuf::Buffer)
637639
state = stream.state
638640
input = buffermem(inbuf)
639-
makemargin!(outbuf, minoutsize(stream.codec, input))
640-
Δin, Δout, state.code = process(stream.codec, input, marginmem(outbuf), state.error)
641+
GC.@preserve inbuf makemargin!(outbuf, minoutsize(stream.codec, input))
642+
Δin, Δout, state.code = GC.@preserve inbuf outbuf process(stream.codec, input, marginmem(outbuf), state.error)
641643
@debug(
642644
"called process()",
643645
code = state.code,
@@ -677,7 +679,7 @@ function readdata!(input::IO, output::Buffer)
677679
navail = bytesavailable(input)
678680
end
679681
n = min(navail, marginsize(output))
680-
Base.unsafe_read(input, marginptr(output), n)
682+
GC.@preserve output Base.unsafe_read(input, marginptr(output), n)
681683
supplied!(output, n)
682684
nread += n
683685
return nread
@@ -691,10 +693,12 @@ function writedata!(output::IO, input::Buffer)
691693
end
692694
nwritten::Int = 0
693695
while buffersize(input) > 0
694-
n = Base.unsafe_write(output, bufferptr(input), buffersize(input))
696+
n = GC.@preserve input Base.unsafe_write(output, bufferptr(input), buffersize(input))
695697
consumed!(input, n)
696698
nwritten += n
699+
GC.safepoint()
697700
end
701+
GC.safepoint()
698702
return nwritten
699703
end
700704

0 commit comments

Comments
 (0)