> simpleToggle2 :: IORef Bool -> IORef Bool -> IO (Just (Bool,Bool)) > > which attempts to flip the two IORefs from True to False (if > they are both True); > otherwise returning their actual values. Then you could code > this something like this > (no I'm not going to check if it passes GHC) > > simpleToggle2 ioRef1 ioRef2 = > do > res <- atomicModifyIORef ioRef1 (\ contents1 -> > unsafePerformIO (atomicModifyIORef ioRef2 (\ contents2 -> > if contents1 && contents2 > then > (False,(False,Nothing)) > else > (contents2,(contents1,Just (contents1,contents2))) > ) > ) > seq res (return res) > > Then the first atomicModifyIORef replaces the contents of > ioRef1 by a thunk, and > returns another thunk. The seq then proceeds to evaluate > this thunk, causing > the unsafePerformIO to be run, which changes ioRef2. > > There IS a potential problem, because if you run > simpleToggle2 on the same ioRef > > simpleToggle2 ioRef ioRef > > or if two threads run simpleToggle2 simultaneously on the > same ioRefs but in opposite order > > simpleToggle2 ioRef1 ioRef2 || simpleToggle2 ioRef2 ioRef1
Don't you run into a problem even if the two threads use the same ordering? Suppose - thread 1 does the atomicModifyIORef, and gets preempted before doing the seq - thread 2 does its own atomicModifyIORef, and the seq. Thread 2 gets an inconsistent view of the IORefs. right? Simon _______________________________________________ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi