Is it true that an exception is always terminates the thread?
rrnewton at gmail.com
Tue Jan 24 16:25:37 CET 2012
This is related but somewhat tangential --
*Why isn't there a tryReadChan?* It looks like it would be implementable
with the current Chan representation in terms of tryTakeMVar. Especially
since isEmptyChan is deprecated this would be nice to have.
Because of missing tryReadChan there is no non-blocking way to read data
resident in a Chan (i.e. flush it -- in this case because I was in an
exception handler and wanted to flush out what was left in memory in a
Chan). I found myself rolling my own in the form of the following data
structure to get around this:
-- Chan's don't quite do the trick. Here's something simpler. It
-- keeps a buffer of elemnts and an MVar to signal "end of stream".
-- This it separates blocking behavior from data access.
data Buffer a = Buf (MVar ()) (IORef [a])
newBuffer :: IO (Buffer a)
newBuffer = do
mv <- newEmptyMVar
ref <- newIORef 
return (Buf mv ref)
writeBuffer :: Buffer a -> a -> IO ()
writeBuffer (Buf mv ref) x = do
b <- isEmptyMVar mv
then atomicModifyIORef ref (\ ls -> (x:ls,()))
else error "writeBuffer: cannot write to closed Buffer"
-- | Signal completion.
closeBuffer :: Buffer a -> IO ()
closeBuffer (Buf mv _) = putMVar mv ()
peekBuffer :: Buffer a -> IO [a]
peekBuffer (Buf _ ref) = liftM reverse $ readIORef ref
-- Returns a lazy list, just like getChanContents:
getBufferContents :: Buffer a -> IO [a]
getBufferContents buf@(Buf mv ref) = do
chan <- newChan
let loop = do
grabbed <- atomicModifyIORef ref (\ ls -> (, reverse ls))
mapM_ (writeChan chan . Just) grabbed
mayb <- tryTakeMVar mv -- Check if we're done.
case mayb of
Nothing -> threadDelay 10000 >> loop
Just () -> writeChan chan Nothing
ls <- getChanContents chan
return (map fromJust $
takeWhile isJust ls)
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Glasgow-haskell-users