[Haskell-cafe] two problems with Data.Binary and Data.ByteString

Tim Newsham newsham at lava.net
Wed Aug 13 20:39:07 EDT 2008


So am I understanding you correctly that you believe this is not
a bug?  That the use Data.Binary.decodeFile function leaks a file
descriptor and this is proper behavior?

I still don't understand your explanation of how isEmpty can
return True without having read to EOF.  The ByteString continues
to contain more data until an EOF is reached.  Doesn't one of

          return (B.null s && L.null ss)

force getContents to read until EOF?

On Wed, 13 Aug 2008, Don Stewart wrote:
> newsham:
>> Ok, surely at least everyone must agree that this is a bug:
>>
>>   force :: Word8 -> IO Word8
>>   force x = print x >> return x
>>   -- force = return . (`using` rnf)
>>
>>   main = do
>>       d <- force =<< decodeFile stateFile
>>       encodeFile stateFile d
>>       where stateFile = "1word32.bin"
>>
>> test8.hs: 1word32.bin: openBinaryFile: resource busy (file is locked)
>>
>
> Remember that
>
>    decodeFile f = liftM decode (L.readFile f)
>
> and
>
>    readFile :: FilePath -> IO ByteString
>    readFile f = openBinaryFile f ReadMode >>= hGetContents
>
> where hGetContents sits in a loop, reading chunks,
>
>    loop = do
>        c <- S.hGetNonBlocking h k
>        if S.null c
>          then do eof <- hIsEOF h
>                  if eof then hClose h >> return Empty
>                         else hWaitForInput h (-1)
>                           >> loop
>          else do cs <- lazyRead
>                  return (Chunk c cs)
>
> while isEmpty is just,
>
>    isEmpty :: Get Bool
>    isEmpty = do
>        S s ss _ <- get
>        return (B.null s && L.null ss)
>
> That is, it checks the parsed chunk, it doesn't demand any more reading be done.
>
> So the only way you're going to get that Handle closed by readFile is to ensure
> you read till EOF is hit. After you decode, just ask keep asking for bytes till EOF,
> or close it yourself,
>
>    decodeFile f = do
>        h  <- openFile f ReadMode
>        ss <- L.hGetContents h
>        let e = decode ss
>        rnf e `seq` hClose h
>
> or some such, where you can confirm the decoding as taken place.
>

Tim Newsham
http://www.thenewsh.com/~newsham/


More information about the Haskell-Cafe mailing list