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

2012-01-24 Thread Johan Brinch
On Fri, Jan 13, 2012 at 00:14, Johan Brinch  wrote:
> Also, if the GHC IO system is using STM internally, what would be the
> correct way to say write a file? (where the IO action can be retried
> safely but have to run at least once, idempotent?). Please don't say
> "don't" :-)

I now believe that the correct answer is simply "don't". For anyone
who finds this thread later and wonder what happened:

I refactored the code to never use IO inside of STM transactions.
Instead, I'm now using the ErrorT IO STM to abort the transaction
early with an IO action that needs to be run before a retry. Aborting
with throwError doesn't rollback the transaction, which means one has
to be extremely careful as to what state is manipulated before
entering clean code (without any throwErrors).

This seems a lot more safe than doing IO inside the STM transactions
which has completely unpredictable (for me, at least) side effects.

-- 
Johan Brinch

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


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

2012-01-12 Thread Johan Brinch
On Thu, Jan 12, 2012 at 22:56, Brandon Allbery  wrote:
> On Thu, Jan 12, 2012 at 16:50, Andrew Coppin 
> wrote:
>>
>> My guess is that your "debug printing" is causing something to be
>> evaluated when it otherwise wouldn't be, causing a transaction to begin
>> within a transaction.
>
>
> My guess is something is being lazily evaluated as usual, but if that is
> forced within a transaction, well, last I checked the GHC I/O system used
> STM internally so unsafePerformIO debug prints could well cause nested
> transactions.
>

This could be it. If I'm computing a value atomically and then using
this value in another transaction, I may nest transactions if the
value isn't forced?

x <- atomically $ foo
let x' = someOp x
atomically $ bar x'

Is it necessary to use seq here, or is it merely the debug printing
that's getting in the way?


Also, if the GHC IO system is using STM internally, what would be the
correct way to say write a file? (where the IO action can be retried
safely but have to run at least once, idempotent?). Please don't say
"don't" :-)

-- 
Johan Brinch

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


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

2012-01-12 Thread Joey Adams
On Thu, Jan 12, 2012 at 7:48 AM, Johan Brinch  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

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


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

2012-01-12 Thread Brandon Allbery
On Thu, Jan 12, 2012 at 16:50, Andrew Coppin wrote:

> My guess is that your "debug printing" is causing something to be
> evaluated when it otherwise wouldn't be, causing a transaction to begin
> within a transaction.
>

My guess is something is being lazily evaluated as usual, but if that is
forced within a transaction, well, last I checked the GHC I/O system used
STM internally so unsafePerformIO debug prints could well cause nested
transactions.

-- 
brandon s allbery  allber...@gmail.com
wandering unix systems administrator (available) (412) 475-9364 vm/sms
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


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

2012-01-12 Thread Andrew Coppin

On 12/01/2012 12:48 PM, Johan Brinch wrote:


I'm not using any unsafe IO


OK, good...


(only for debug printing)


...ah. It seems we have reached a contradiction.


Where is a transaction being nested?


My guess is that your "debug printing" is causing something to be 
evaluated when it otherwise wouldn't be, causing a transaction to begin 
within a transaction.


I could, however, be horribly wrong about that...

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


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

2012-01-12 Thread Johan Brinch
On Thu, Jan 12, 2012 at 14:56, Antoine Latter  wrote:
> Where is 'evalCacheSTM' defined?

Here you go:
https://gist.github.com/8dbff672a14533c70aa2

-- 
Johan Brinch

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


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

2012-01-12 Thread Antoine Latter
On Thu, Jan 12, 2012 at 6:48 AM, Johan Brinch  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?
>

Where is 'evalCacheSTM' defined?

> The behaviour is consistent on GHC 7.4.0 RC and GHC 7.2.2 (stable).
>
> That function that's being run can be found here:
> https://gist.github.com/30b94760abc27b05ec7c
>
> And here is the last output from the runtime system:
> https://gist.github.com/4356ae541895becb4169
>
>
> Any ideas to track this down will be greatly appreciated!
>
> --
> Johan Brinch,
> Dept. of Computer Science,
> University of Copenhagen
>
> ___
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe