Suggestion: use an IORef and asynchronous exceptions, see below for untested code.
On Wed, Dec 21, 2011 at 6:52 AM, Fedor Gogolev <[email protected]> wrote: > Hello. I'm trying to get some threads that I can stop and get last > values that was computed (and that values are IO values, in fact). > Here is my first approach: > > module Main where > > import Control.Concurrent (MVar, threadDelay, forkIO, newMVar, > putMVar, readMVar) > > tick :: Int -> IO Int > tick v = return $ v + 1 > > loop :: MVar Bool -> a -> (a -> IO a) -> IO a > loop var init loopfun = do > next <- loopfun init > shouldStop <- readMVar var > case shouldStop of > True -> return next > False -> loop var next loopfun loop :: IORef a -> (a -> IO a) -> IO () loop var loopfun = readIORef var >>= go where go val = do next <- loopfun val writeIORef var next go next > runLoop :: Int -> IO () > runLoop timeout = do > var <- newMVar False > forkIO $ threadDelay timeout >> putMVar var True > value <- loop var 0 tick > print value runLoop timeout = do var <- newIORef 0 lock <- newEmptyMVar loopTid <- forkIO $ loop var tick >> putMVar lock () delayTid <- forkIO $ threadDelay timeout >> killThread loopTid >> putMVar lock () takeMVar lock killThread delayTid value <- readIORef var print value > main :: IO () > main = runLoop 30000000 > > The problem is that it looks a little messy and what's worse it leaks > memory. So I'm wondering if there is a better approach to do so or > some fix to memory leak. Again, code above is untested and was written on my e-mail client =). But the idea seems fine. Cheers, -- Felipe. _______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
