stg_block_throwto_finally
{
- // unlock the throwto message
- unlockClosure(StgTSO_block_info(CurrentTSO), stg_MSG_THROWTO_info);
+ // unlock the throwto message, but only if it wasn't already
+ // unlocked. It may have been unlocked if we revoked the message
+ // due to an exception being raised during threadPaused().
+ if (StgHeader_info(StgTSO_block_info(CurrentTSO)) == stg_WHITEHOLE_info) {
+ unlockClosure(StgTSO_block_info(CurrentTSO), stg_MSG_THROWTO_info);
+ }
jump StgReturn;
}
if (tso->what_next == ThreadComplete || tso->what_next == ThreadKilled) {
return;
}
+ while (tso->what_next == ThreadRelocated) {
+ tso = tso->_link;
+ }
// Remove it from any blocking queues
removeFromQueues(cap,tso);
if (tso->what_next == ThreadComplete || tso->what_next == ThreadKilled) {
return;
}
+ while (tso->what_next == ThreadRelocated) {
+ tso = tso->_link;
+ }
// Remove it from any blocking queues
removeFromQueues(cap,tso);
fprintCCS_stderr(tso->prof.CCCS);
}
#endif
-
- while (tso->what_next == ThreadRelocated) {
- tso = tso->_link;
- }
+ // ASSUMES: the thread is not already complete or dead, or
+ // ThreadRelocated. Upper layers should deal with that.
+ ASSERT(tso->what_next != ThreadComplete &&
+ tso->what_next != ThreadKilled &&
+ tso->what_next != ThreadRelocated);
// mark it dirty; we're about to change its stack.
dirty_TSO(cap, tso);
sp = tso->sp;
- // ASSUMES: the thread is not already complete or dead. Upper
- // layers should deal with that.
- ASSERT(tso->what_next != ThreadComplete && tso->what_next != ThreadKilled);
-
if (stop_here != NULL) {
updatee = stop_here->updatee;
} else {