Is it true that an exception is always terminates the thread?

Ryan Newton rrnewton at
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
  if b
     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
  forkIO loop
  ls <- getChanContents chan
  return (map fromJust $
  takeWhile isJust ls)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the Glasgow-haskell-users mailing list