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

2012-01-24 Thread Johan Brinch
On Fri, Jan 13, 2012 at 00:14, Johan Brinch brin...@gmail.com 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 Antoine Latter
On Thu, Jan 12, 2012 at 6:48 AM, Johan Brinch brin...@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?


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


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

2012-01-12 Thread Johan Brinch
On Thu, Jan 12, 2012 at 14:56, Antoine Latter aslat...@gmail.com 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 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 Brandon Allbery
On Thu, Jan 12, 2012 at 16:50, Andrew Coppin andrewcop...@btinternet.comwrote:

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

___
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 allber...@gmail.com wrote:
 On Thu, Jan 12, 2012 at 16:50, Andrew Coppin andrewcop...@btinternet.com
 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