Simon Marlow wrote: [snip] > > Ok, so it relies crucially on the fact that the 'if' causes evaluation. > (you might have written it to be more lazy, so that the pair was > returned immediately without evaluating contents1 first, for example). > > In that case, yes I agree it is horrible :) [snip] Flattery like that will get you nowhere. However in general I think we can hide some of the horribleness from the user:
modify2IORefs :: IORef a -> IORef b -> (a -> b -> (a,b,c)) -> IO c modify2IORefs ioRefA ioRefB updateFn = do res <- atomicModifyIORef ioRefA (\ a0 -> unsafePerformIO (do atomicModifyIORef ioRefB (\ b0 -> let (a1,b1,c) = updateFn a0 b0 in a0 `seq` b0 `seq` (b1,(a1,c)) ) ) ) block (res `seq` return res) Modulo whatever stupid type errors I have made, I think this should provide a safe atomic update of two IORefs, except that you can get non-termination should you set up circular dependencies. However the latter problem (except that you will get deadlock) can occur if you try to write modify2MVars :: MVar a -> MVar b -> (a -> b -> (a,b,c)) -> IO c and are I fear unsolvable, without a global lock. I am not sure if all those seqs are necessary, but as Simon PJ would say, my brain is hurting. _______________________________________________ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi