Skip to content

Commit ab97927

Browse files
committed
Separate out finalization from close, to avoid exceptions in finalization
1 parent c75420d commit ab97927

File tree

1 file changed

+17
-9
lines changed

1 file changed

+17
-9
lines changed

src/iconv.jl

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,15 @@ type StringDecoder{S<:IO} <: IO
5757
skip::Int
5858
end
5959

60+
# This is called during GC, just make sure C memory is returned, don't throw errors
61+
function finalize(s::Union{StringEncoder, StringDecoder})
62+
if s.cd != C_NULL
63+
iconv_close(s.cd)
64+
s.cd = C_NULL
65+
end
66+
nothing
67+
end
68+
6069
function iconv!(cd::Ptr{Void}, inbuf::Vector{UInt8}, outbuf::Vector{UInt8},
6170
inbufptr::Ref{Ptr{UInt8}}, outbufptr::Ref{Ptr{UInt8}},
6271
inbytesleft::Ref{Csize_t}, outbytesleft::Ref{Csize_t})
@@ -135,7 +144,7 @@ function StringEncoder(ostream::IO, to::ASCIIString, from::ASCIIString="UTF-8")
135144
s = StringEncoder(ostream, cd, inbuf, outbuf,
136145
Ref{Ptr{UInt8}}(pointer(inbuf)), Ref{Ptr{UInt8}}(pointer(outbuf)),
137146
Ref{Csize_t}(0), Ref{Csize_t}(BUFSIZE))
138-
finalizer(s, close)
147+
finalizer(s, finalize)
139148
s
140149
end
141150

@@ -157,11 +166,10 @@ function flush(s::StringEncoder)
157166
end
158167

159168
function close(s::StringEncoder)
160-
s.cd == C_NULL && return s
161169
flush(s)
162170
iconv_reset!(s)
163-
iconv_close(s.cd)
164-
s.cd = C_NULL
171+
# Make sure C memory/resources are returned
172+
finalize(s)
165173
# flush() wasn't able to empty input buffer, which cannot happen with correct data
166174
s.inbytesleft[] == 0 || error("iconv error: incomplete byte sequence at end of input")
167175
end
@@ -188,7 +196,7 @@ function StringDecoder(istream::IO, from::ASCIIString, to::ASCIIString="UTF-8")
188196
s = StringDecoder(istream, cd, inbuf, outbuf,
189197
Ref{Ptr{UInt8}}(pointer(inbuf)), Ref{Ptr{UInt8}}(pointer(outbuf)),
190198
Ref{Csize_t}(0), Ref{Csize_t}(BUFSIZE), 0)
191-
finalizer(s, close)
199+
finalizer(s, finalize)
192200
s
193201
end
194202

@@ -221,10 +229,10 @@ function eof(s::StringDecoder)
221229
end
222230

223231
function close(s::StringDecoder)
224-
s.cd == C_NULL && return s
225-
iconv_close(s.cd)
226-
s.cd = C_NULL
227-
# fill_buffer!() wasn't able to empty input buffer, which cannot happen with correct data
232+
iconv_reset!(s)
233+
# Make sure C memory/resources are returned
234+
finalize(s)
235+
# iconv_reset!() wasn't able to empty input buffer, which cannot happen with correct data
228236
s.inbytesleft[] == 0 || error("iconv error: incomplete byte sequence at end of input")
229237
end
230238

0 commit comments

Comments
 (0)