
Simon Marlow wrote:
It's a hard problem. Trying to code up takeEitherMVar by hand always seems to lead to solutions with race conditions - I can't see a way to do it.
The following solution should be free from race conditions, takeEitherMVar :: MVar a -> MVar b -> IO (Either a b) takeEitherMVar mva mvb = do ma <- tryTakeMVar mva case ma of Just a -> return (Left a) Nothing -> do mb <- tryTakeMVar mvb case mb of Just b -> return (Right b) Nothing -> takeEitherMVar mva mvb but it has an efficiency problem, though...
Perhaps takeEitherMVar should be provided as a primitive, but I'm concerned that the same problems will crop up if we tried to implement takeEitherMVar in a multi-threaded runtime
Also, what if you wanted to choose between three variables?
So I think in order to do this you have to build another abstraction around MVars. I've attached some code I just hacked up to do just that; it's untested (but compiles), and has a couple of known deficiencies, but it might be along the right lines.
Thanks, I'll see if I can understand that... -- Thomas H