limited-scope retry?

Abraham Egnor abe.egnor at
Thu Apr 21 10:47:27 EDT 2005

Suppose that a program using the Control.Concurrent.STM module had a
producer/consumer setup - one thread writing to a channel, the other
thread reading from the channel.  It seems natural to want a function
that the producer can call that will block until the consumer has
finished consuming everything currently in the channel.  The way I
first tried implementing this was:

-- types simplified for this example
flush :: TChan () -> STM ()
flush chan =
  do e <- isEmptyTChan
        if not e then retry else return ()

Used in isolation, i.e.

atomically $ writeTChan chan ()
atomically $ flush chan

it works fine.  However, when composed (atomically $ writeTChan chan
() >> flush chan), it causes a race condition, usually resulting in
deadlock, as the "retry" in flush replays the call to writeTChan as

This situation begs for a way to limit the scope of "retry", in which
case flush would be:

flush chan = limitRetry $
  do e <- isEmptyTChan
        if not e then retry else return ()


More information about the Glasgow-haskell-users mailing list