[commit: packages/haskeline] master: Extending concurrent print function to Win32 backend. (0640f91)
git at git.haskell.org
git at git.haskell.org
Tue Dec 13 19:21:40 UTC 2016
Repository : ssh://git@git.haskell.org/haskeline
On branch : master
Link : http://git.haskell.org/packages/haskeline.git/commitdiff/0640f9125741368505ad58ec224d3fdc9a55d266
>---------------------------------------------------------------
commit 0640f9125741368505ad58ec224d3fdc9a55d266
Author: Bakhtiyar Neyman <b.neymanov at gmail.com>
Date: Mon Feb 15 21:57:58 2016 -0800
Extending concurrent print function to Win32 backend.
>---------------------------------------------------------------
0640f9125741368505ad58ec224d3fdc9a55d266
System/Console/Haskeline/Backend/Posix.hsc | 18 +-----------------
System/Console/Haskeline/Backend/Win32.hsc | 26 ++++++++++++++------------
System/Console/Haskeline/Term.hs | 18 +++++++++++++++++-
3 files changed, 32 insertions(+), 30 deletions(-)
diff --git a/System/Console/Haskeline/Backend/Posix.hsc b/System/Console/Haskeline/Backend/Posix.hsc
index c8d7b14..11cbe2c 100644
--- a/System/Console/Haskeline/Backend/Posix.hsc
+++ b/System/Console/Haskeline/Backend/Posix.hsc
@@ -294,26 +294,10 @@ posixRunTerm hs layoutGetters keys wrapGetEvent evalBackend = do
, externalPrint = writeChan ch . ExternalPrint
}
, closeTerm = do
- -- This hack is needed to grab latest writes from some other thread.
- -- Without it, if you are using another thread to process the logging
- -- and write on screen via exposed externalPrint, latest writes from
- -- this thread are not able to cross the thread boundary in time.
- threadDelay 1
flushEventQueue (putStrOut fileRT) ch
- closeTerm fileRT
+ closeHandles hs
}
-flushEventQueue :: (String -> IO ()) -> Chan Event -> IO ()
-flushEventQueue print' eventChan = loop
- where loop = do
- flushed <- isEmptyChan eventChan
- if flushed then return () else do
- event <- readChan eventChan
- case event of
- ExternalPrint str -> do
- print' (str ++ "\n") >> loop
- _ -> do loop
-
type PosixT m = ReaderT Encoder (ReaderT Handles m)
runPosixT :: Monad m => Encoder -> Handles -> PosixT m a -> m a
diff --git a/System/Console/Haskeline/Backend/Win32.hsc b/System/Console/Haskeline/Backend/Win32.hsc
index d9c0934..95a7b5b 100644
--- a/System/Console/Haskeline/Backend/Win32.hsc
+++ b/System/Console/Haskeline/Backend/Win32.hsc
@@ -380,17 +380,20 @@ win32Term = do
hs <- consoleHandles
ch <- liftIO newChan
fileRT <- liftIO $ fileRunTerm stdin
- return fileRT {
- termOps = Left TermOps {
- getLayout = getBufferSize (hOut hs)
- , withGetEvent = withWindowMode hs
- . win32WithEvent hs ch
- , saveUnusedKeys = saveKeys ch
- , evalTerm = EvalTerm (runReaderT' hs . runDraw)
- (Draw . lift)
- },
- closeTerm = closeHandles hs
- }
+ return fileRT
+ { termOps = Left TermOps {
+ getLayout = getBufferSize (hOut hs)
+ , withGetEvent = withWindowMode hs
+ . win32WithEvent hs ch
+ , saveUnusedKeys = saveKeys ch
+ , evalTerm = EvalTerm (runReaderT' hs . runDraw)
+ (Draw . lift)
+ , externalPrint = writeChan ch . ExternalPrint
+ }
+ , closeTerm = do
+ flushEventQueue (putStrOut fileRT) ch
+ closeHandles hs
+ }
win32WithEvent :: MonadException m => Handles -> Chan Event
-> (m Event -> m a) -> m a
@@ -545,4 +548,3 @@ clearScreen = do
liftIO $ fillConsoleChar h ' ' windowSize origin
liftIO $ fillConsoleAttribute h attr windowSize origin
setPos origin
-
diff --git a/System/Console/Haskeline/Term.hs b/System/Console/Haskeline/Term.hs
index 0e60278..5186a12 100644
--- a/System/Console/Haskeline/Term.hs
+++ b/System/Console/Haskeline/Term.hs
@@ -46,6 +46,23 @@ data TermOps = TermOps
, externalPrint :: String -> IO ()
}
+-- This hack is needed to grab latest writes from some other thread.
+-- Without it, if you are using another thread to process the logging
+-- and write on screen via exposed externalPrint, latest writes from
+-- this thread are not able to cross the thread boundary in time.
+flushEventQueue :: (String -> IO ()) -> Chan Event -> IO ()
+flushEventQueue print' eventChan = yield >> loopUntilFlushed
+ where loopUntilFlushed = do
+ flushed <- isEmptyChan eventChan
+ if flushed then return () else do
+ event <- readChan eventChan
+ case event of
+ ExternalPrint str -> do
+ print' (str ++ "\n") >> loopUntilFlushed
+ ErrorEvent e -> throwIO e
+ -- We don't want to raise exceptions when doing cleanup.
+ _ -> do loopUntilFlushed
+
-- | Operations needed for file-style interaction.
--
-- Backends can assume that getLocaleLine, getLocaleChar and maybeReadNewline
@@ -200,4 +217,3 @@ hGetLocaleLine = guardedEOF $ \h -> do
liftIO $ if buff == NoBuffering
then fmap BC.pack $ System.IO.hGetLine h
else BC.hGetLine h
-
More information about the ghc-commits
mailing list