diff options
Diffstat (limited to 'rts/Threads.c')
-rw-r--r-- | rts/Threads.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/rts/Threads.c b/rts/Threads.c index 6050549d64..39616655ab 100644 --- a/rts/Threads.c +++ b/rts/Threads.c @@ -803,9 +803,14 @@ loop: // There are takeMVar(s) waiting: wake up the first one tso = q->tso; - mvar->head = q->link; - if (mvar->head == (StgMVarTSOQueue*)&stg_END_TSO_QUEUE_closure) { + mvar->head = q = q->link; + if (q == (StgMVarTSOQueue*)&stg_END_TSO_QUEUE_closure) { mvar->tail = (StgMVarTSOQueue*)&stg_END_TSO_QUEUE_closure; + } else { + if (info == &stg_MVAR_CLEAN_info) { + // Resolve #18919. + dirty_MVAR(&cap->r, (StgClosure*)mvar, mvar->value); + } } ASSERT(tso->block_info.closure == (StgClosure*)mvar); @@ -829,10 +834,8 @@ loop: // If it was a readMVar, then we can still do work, // so loop back. (XXX: This could take a while) - if (why_blocked == BlockedOnMVarRead) { - q = ((StgMVarTSOQueue*)q)->link; + if (why_blocked == BlockedOnMVarRead) goto loop; - } ASSERT(why_blocked == BlockedOnMVar); |