haskell / bytestring

An efficient compact, immutable byte string type (both strict and lazy) suitable for binary or 8-bit character data.
http://hackage.haskell.org/package/bytestring
Other
291 stars 141 forks source link

hPutStrLn is not atomic #200

Open AndreasPK opened 4 years ago

AndreasPK commented 4 years ago

Since the newline is added in an additional hPut call another thread might write to the handle in the meantime.

I think that's acceptable but should be documented.

-- | Write a ByteString to a handle, appending a newline byte
hPutStrLn :: Handle -> ByteString -> IO ()
hPutStrLn h ps
    | length ps < 1024 = hPut h (ps `snoc` 0x0a)
    | otherwise        = hPut h ps >> hPut h (singleton (0x0a)) -- don't copy
Bodigrim commented 4 months ago

Following https://www.snoyman.com/blog/2016/11/haskells-missing-concurrency-basics/, let's reopen this. I think the mitigation with length ps < 1024 = hPut h (pssnoc0x0a) is both insufficient and inefficient.

BebeSparkelSparkel commented 4 months ago

I am looking at the implementation of hPutStrLn and do not see an easy solution without copying. Perhaps, adding hPutStrLnAtomic is the solution.

A related discussion https://discourse.haskell.org/t/explain-ghc-internal-io-handle-text-hputstr/9389