Skip to content

hPutStrLn in multiple threads #442

Closed

Description

@worm2fed

Function to print text with newline performs it as two separate actions - first is to print message and second - to
print newline symbol.
This way there is issues with computations in multiple threads, so newline symbol sometimes printed in wrong place.

Possible solution here is to redefine hPutStrLn like this:

hPutStrLn :: Handle -> Text -> IO ()
hPutStrLn h t = hPutStr h $ t <> '\n'

Not sure what is the reason of current implementation..
I found that issue when used co-log and I've provided PR with a fix (co-log/co-log#243), but the source problem is text library.

Activity

  1. phadej commented on Jun 6, 2022

    @phadej
    Contributor

    I'd rather document that none of IO actions in Data.Text.IO are thread-safe. Making them thread-safe would add an overhead for people who don't need that.

    EDIT: And e.g. if people need to output two lines, thread-safe hPutStrLn won't help. hPutStrLn $ firstLne <> "\n" <> secondLine is inefficient (performs unnecessary copying).

  2. worm2fed commented on Jun 6, 2022

    @worm2fed
    Author

    @phadej yes, such a note can be useful to avoid confusion

  3. Bodigrim commented on Jun 6, 2022

    @Bodigrim
    Contributor

    bytestring defines hPutStrLn as below:

    hPutStrLn :: Handle -> ByteString -> IO ()
    hPutStrLn h ps
        | length ps < 1024 = hPut h (ps `B.snoc` 0x0a)
        | otherwise        = hPut h ps >> hPut h (B.singleton 0x0a) -- don't copy

    This is still not atomic, but much less annoying in practice. I think doing the same trick in text + expanding documentation is a reasonable way to proceed.

  4. worm2fed commented on Jun 21, 2022

    @worm2fed
    Author

    bytestring defines hPutStrLn as below:

    hPutStrLn :: Handle -> ByteString -> IO ()
    hPutStrLn h ps
        | length ps < 1024 = hPut h (ps `B.snoc` 0x0a)
        | otherwise        = hPut h ps >> hPut h (B.singleton 0x0a) -- don't copy

    @Bodigrim but length can be expensive O(n)

  5. Bodigrim commented on Jun 22, 2022

    @Bodigrim
    Contributor

    @axman6-da hPutBuilder is a sensible addition, but I'm not sure it provides guarantees of atomicity even in bytestring.

  6. Bodigrim commented on Feb 21, 2024

    @Bodigrim
    Contributor

    This seems to be a duplicate of #242.

    It would be nice if someone has energy if not fix it completely then at least alleviate in typical scenarios.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions