Jules Bean wrote: > ChrisK 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 >> >> The best way to make this safe that I know of is: >> >>> res <- block $ do >>> tickerId <- forkIO ticker >>> unblock act `finally` killThread tickerId > > > ...but with a change that Simon M just checked in to GHC head, this will > now spawn 'ticker' in blocked state, so you won't be able to kill it. > You would therefore want unblock $ forkIO ticker or forkIO $ unblock ticker > > I'm not sure if there is a strong reason to prefer one over the other. > > Jules
That is new. Ah, I see GHC.Conc.forkIO now has a note: > GHC note: the new thread inherits the /blocked/ state of the parent > (see 'Control.Exception.block'). BUT...doesn't this change some of the semantics of old code that used forkIO ? I wanted a way to control the blocked status of new threads, since this makes it easier to be _sure_ some race conditions will never happen. And so my new preferred way of writing this is now: > -- we are in parent's blocked state, so make the ticker explicit: > res <- bracket (forkIO (unblock ticker)) > killThread > const act -- act runs in parent's blocked state -- Chris _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe