| > I noticed that isEmptyChan blocks if the channel is already | > waited on by readChan, is this the intended behaviour? | > At least I was a bit surprised by a blocking predicate.. | | I agree this doesn't seem right. Looking at the implementation though, | I can't see an easy way to fix it - any suggestions?
Just to clarify. The offending module is Control.Concurrent.Chan, and I reproduce the key code below. The channel is represented by a pair of MVars, which point to head and tail (respectively) of a list composed of MVars. The difficulty is that a blocked reader will own the read-end MVar, so isEmptyChan blocks. That makes isEmptyChan essentially useless. Either it should be removed, or the implementation of Chan needs to be elaborated to support isEmptyChan. Volunteers? Simon -- A channel is represented by two @[EMAIL PROTECTED] keeping track of the two ends -- of the channel contents,i.e., the read- and write ends. Empty @[EMAIL PROTECTED] -- are used to handle consumers trying to read from an empty channel. -- |'Chan' is an abstract type representing an unbounded FIFO channel. data Chan a = Chan (MVar (Stream a)) (MVar (Stream a)) type Stream a = MVar (ChItem a) data ChItem a = ChItem a (Stream a) -- See the Concurrent Haskell paper for a diagram explaining the -- how the different channel operations proceed. -- |Build and returns a new instance of 'Chan'. newChan :: IO (Chan a) newChan = do hole <- newEmptyMVar read <- newMVar hole write <- newMVar hole return (Chan read write) -- To put an element on a channel, a new hole at the write end is created. -- What was previously the empty @MVar@ at the back of the channel is then -- filled in with a new stream element holding the entered value and the -- new hole. -- |Write a value to a 'Chan'. writeChan :: Chan a -> a -> IO () writeChan (Chan _read write) val = do new_hole <- newEmptyMVar modifyMVar_ write $ \old_hole -> do putMVar old_hole (ChItem val new_hole) return new_hole -- |Read the next value from the 'Chan'. readChan :: Chan a -> IO a readChan (Chan read _write) = do modifyMVar read $ \read_end -> do (ChItem val new_read_end) <- readMVar read_end -- Use readMVar here, not takeMVar, -- else dupChan doesn't work return (new_read_end, val) -- |Returns 'True' if the supplied 'Chan' is empty. isEmptyChan :: Chan a -> IO Bool isEmptyChan (Chan read write) = do withMVar read $ \r -> do w <- readMVar write let eq = r == w eq `seq` return eq _______________________________________________ Glasgow-haskell-users mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users