
Belatedly I realized that this answer should have been going to the list: --------------- ChrisK wrote: On Mittwoch, 28. November 2007, you wrote:
A safer gimmick...
Ben Franksen wrote:
tickWhileDoing :: String -> IO a -> IO a tickWhileDoing msg act = do hPutStr stderr msg >> hPutChar stderr ' ' >> hFlush stderr start_time <- getCPUTime tickerId <- forkIO ticker
... an async exception here will leave the ticker runnning....
res <- act `finally` killThread tickerId
Thanks for spotting this loophole. I keep forgetting people tend to hit Ctrl-C whenever they feel like it... ;-) Thinking some more about this, I realise that the async exception could also come from somewhere inside the Haskell program (e.g. from a killThread like I did myself in the next line.) So the fix below makes this whole things more robust indeed.
The best way to make this safe that I know of is:
res <- block $ do tickerId <- forkIO ticker unblock act `finally` killThread tickerId
Yes. Cheers Ben