Skip to content

Commit ff2e987

Browse files
committed
Drop read thread
Previously we would read events from the console in a separate thread which would be killed after the needed event was read. There are a few issues with this approach: * it is expensive, requiring the creation and destruction of a thread with every read event * it is racy, since the thread may be killed after an even has been read from the console but before it has been pushed to the event TChan * we may read too much: the read loop thread may read more input than Haskeline was supposed to read (see GHC #21047).
1 parent 30aafaf commit ff2e987

File tree

2 files changed

+8
-11
lines changed

2 files changed

+8
-11
lines changed

System/Console/Haskeline/Backend/Win32.hsc

-2
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,6 @@ eventReader :: HANDLE -> IO [Event]
6666
eventReader h = do
6767
let waitTime = 500 -- milliseconds
6868
ret <- c_WaitForSingleObject h waitTime
69-
yield -- otherwise, the above foreign call causes the loop to never
70-
-- respond to the killThread
7169
if ret /= (#const WAIT_OBJECT_0)
7270
then eventReader h
7371
else do

System/Console/Haskeline/Term.hs

+8-9
Original file line numberDiff line numberDiff line change
@@ -138,18 +138,17 @@ keyEventLoop readEvents eventChan = do
138138
isEmpty <- atomically $ isEmptyTChan eventChan
139139
if not isEmpty
140140
then atomically $ readTChan eventChan
141-
else do
142-
tid <- forkIO $ handleErrorEvent readerLoop
143-
atomically (readTChan eventChan) `finally` killThread tid
141+
else handleErrorEvent readerLoop
144142
where
143+
readerLoop :: IO Event
145144
readerLoop = do
146145
es <- readEvents
147-
if null es
148-
then readerLoop
149-
else atomically $ mapM_ (writeTChan eventChan) es
150-
handleErrorEvent = handle $ \e -> case fromException e of
151-
Just ThreadKilled -> return ()
152-
_ -> atomically $ writeTChan eventChan (ErrorEvent e)
146+
case es of
147+
[] -> readerLoop
148+
e : rest -> do atomically $ mapM_ writeTChan rest
149+
return e
150+
151+
handleErrorEvent = handle $ \e -> return (ErrorEvent e)
153152

154153
saveKeys :: TChan Event -> [Key] -> IO ()
155154
saveKeys ch = atomically . writeTChan ch . KeyInput

0 commit comments

Comments
 (0)