summaryrefslogtreecommitdiff
path: root/rts/RaiseAsync.c
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2009-10-14 13:16:19 +0000
committerSimon Marlow <marlowsd@gmail.com>2009-10-14 13:16:19 +0000
commitc5f93af1c663ab68f3b18f6a8c3264165a1c8883 (patch)
treea3386b4d068294267e0f34d98ef4d582e7228ab5 /rts/RaiseAsync.c
parent79e9cfa32cc3b94428e1199ce550bb62c50bf8e6 (diff)
downloadhaskell-c5f93af1c663ab68f3b18f6a8c3264165a1c8883.tar.gz
Fix #3578: return a dummy result when an STM transaction is aborted
(see comment for details)
Diffstat (limited to 'rts/RaiseAsync.c')
-rw-r--r--rts/RaiseAsync.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/rts/RaiseAsync.c b/rts/RaiseAsync.c
index 3078cf90ad..6510ce8b07 100644
--- a/rts/RaiseAsync.c
+++ b/rts/RaiseAsync.c
@@ -886,7 +886,17 @@ raiseAsync(Capability *cap, StgTSO *tso, StgClosure *exception,
if (stop_at_atomically) {
ASSERT(stmGetEnclosingTRec(tso->trec) == NO_TREC);
stmCondemnTransaction(cap, tso -> trec);
- tso->sp = frame;
+ tso->sp = frame - 2;
+ // The ATOMICALLY_FRAME expects to be returned a
+ // result from the transaction, which it stores in the
+ // stack frame. Hence we arrange to return a dummy
+ // result, so that the GC doesn't get upset (#3578).
+ // Perhaps a better way would be to have a different
+ // ATOMICALLY_FRAME instance for condemned
+ // transactions, but I don't fully understand the
+ // interaction with STM invariants.
+ tso->sp[1] = (W_)&stg_NO_TREC_closure;
+ tso->sp[0] = (W_)&stg_gc_unpt_r1_info;
tso->what_next = ThreadRunGHC;
return;
}