The Revenge of Finalizers
Simon Marlow
simonmar at microsoft.com
Thu Oct 17 10:13:42 EDT 2002
> 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
More information about the FFI
mailing list