Commit fd70fba0 authored by Simon Marlow's avatar Simon Marlow

Fix a few places where we forgot to close the text codecs (#4029)

Each time you invoke :load in GHCi it resets the CAFs, including
stdin/stdout/stderr, and each of these was allocating a new iconv_t.
parent 7cd42114
......@@ -270,6 +270,7 @@ hSetEncoding :: Handle -> TextEncoding -> IO ()
hSetEncoding hdl encoding = do
withAllHandles__ "hSetEncoding" hdl $ \h_@Handle__{..} -> do
flushCharBuffer h_
closeTextCodecs h_
openTextEncoding (Just encoding) haType $ \ mb_encoder mb_decoder -> do
bbuf <- readIORef haByteBuffer
ref <- newIORef (error "last_decode")
......@@ -572,6 +573,7 @@ hSetBinaryMode handle bin =
withAllHandles__ "hSetBinaryMode" handle $ \ h_@Handle__{..} ->
do
flushCharBuffer h_
closeTextCodecs h_
let mb_te | bin = Nothing
| otherwise = Just localeEncoding
......
......@@ -84,6 +84,9 @@ stdHandleFinalizer :: FilePath -> MVar Handle__ -> IO ()
stdHandleFinalizer fp m = do
h_ <- takeMVar m
flushWriteBuffer h_
case haType h_ of
ClosedHandle -> return ()
_other -> closeTextCodecs h_
putMVar m (ioe_finalizedHandle fp)
-- We have to put the FDs into binary mode on Windows to avoid the newline
......
......@@ -28,7 +28,7 @@ module GHC.IO.Handle.Internals (
wantSeekableHandle,
mkHandle, mkFileHandle, mkDuplexHandle,
openTextEncoding, initBufferState,
openTextEncoding, closeTextCodecs, initBufferState,
dEFAULT_CHAR_BUFFER_SIZE,
flushBuffer, flushWriteBuffer, flushWriteBuffer_, flushCharReadBuffer,
......@@ -50,7 +50,7 @@ module GHC.IO.Handle.Internals (
import GHC.IO
import GHC.IO.IOMode
import GHC.IO.Encoding
import GHC.IO.Encoding as Encoding
import GHC.IO.Handle.Types
import GHC.IO.Buffer
import GHC.IO.BufferedIO (BufferedIO)
......@@ -632,6 +632,11 @@ openTextEncoding (Just TextEncoding{..}) ha_type cont = do
return Nothing
cont mb_encoder mb_decoder
closeTextCodecs :: Handle__ -> IO ()
closeTextCodecs Handle__{..} = do
case haDecoder of Nothing -> return (); Just d -> Encoding.close d
case haEncoder of Nothing -> return (); Just d -> Encoding.close d
-- ---------------------------------------------------------------------------
-- closing Handles
......@@ -657,7 +662,7 @@ trymaybe :: IO () -> IO (Maybe SomeException)
trymaybe io = (do io; return Nothing) `catchException` \e -> return (Just e)
hClose_handle_ :: Handle__ -> IO (Handle__, Maybe SomeException)
hClose_handle_ Handle__{..} = do
hClose_handle_ h_@Handle__{..} = do
-- close the file descriptor, but not when this is the read
-- side of a duplex handle.
......@@ -676,8 +681,7 @@ hClose_handle_ Handle__{..} = do
writeIORef haByteBuffer noByteBuffer
-- release our encoder/decoder
case haDecoder of Nothing -> return (); Just d -> close d
case haEncoder of Nothing -> return (); Just d -> close d
closeTextCodecs h_
-- we must set the fd to -1, because the finalizer is going
-- to run eventually and try to close/unlock it.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment