[Haskell-cafe] STM: "nested atomically" error

Joey Adams joeyadams3.14159 at gmail.com
Thu Jan 12 23:38:49 CET 2012


On Thu, Jan 12, 2012 at 7:48 AM, Johan Brinch <brinchj at gmail.com> wrote:
> Hi all,
>
> I'm seeing the "Control.Concurrent.STM.atomically was nested" error,
> but I just can't figure out what's happening. I'm not using any unsafe
> IO (only for debug printing), and the test program is only running one
> thread. Where is a transaction being nested?
>
> What are the scenarios where this error is reported?

I might as well state the obvious.

The type system prevents this from happening under normal
circumstances.  However, it is possible to circumvent the type system
using, for example, unsafePerformIO or unsafeInterleaveIO:

    nest1 :: IO ()
    nest1 =
        let x = unsafePerformIO $ atomically $ return ()
         in atomically (x `seq` return ())

    nest2 :: IO ()
    nest2 = do
        x <- unsafeInterleaveIO $ atomically $ return ()
        atomically (x `seq` return ())

In both nest1 and nest2, x is a thunk whose evaluation performs an STM
transaction.  In both cases, this produces an "atomically was nested"
error.

On GHC, the Debug.Trace functions internally call a C function called
debugBelch (defined in RtsMessages.c).  These don't appear to use
'atomically' at all.  Thus, I doubt using trace will produce an
"atomically was nested" error.

- Joey



More information about the Haskell-Cafe mailing list