{-# OPTIONS_GHC -fno-full-laziness -fno-cse #-} module AtomicPrint ( atomicPrint, atomicPrintS, atomicPrintNoWait, atomicPrintNoWaitS, ) where import Control.Concurrent import Control.Monad (void) import Data.Text qualified as T import Data.Text.IO.Utf8 qualified as T import Data.Text (Text) import System.IO.Unsafe (unsafePerformIO) {-# NOINLINE mutex #-} mutex :: MVar () mutex = unsafePerformIO (newMVar ()) atomicPrintS :: String -> IO () atomicPrintS = atomicPrint . T.pack atomicPrint :: Text -> IO () atomicPrint text = withMVar mutex $ \() -> T.putStrLn text atomicPrintNoWaitS :: String -> IO () atomicPrintNoWaitS = atomicPrintNoWait . T.pack -- | Does not block, so if you've masked exceptions, nothing will come through here atomicPrintNoWait :: Text -> IO () atomicPrintNoWait text = void $ forkIO $ atomicPrint text