Capability, and it is
- NotBlocked, BlockedOnMsgThrowTo,
- BlockedOnCCall
+ BlockedOnCCall_Interruptible
- or it is masking exceptions (TSO_BLOCKEX)
case BlockedOnBlackHole:
{
- // Revoke the message by replacing it with IND. We're not
- // locking anything here, so we might still get a TRY_WAKEUP
- // message from the owner of the blackhole some time in the
- // future, but that doesn't matter.
- ASSERT(target->block_info.bh->header.info == &stg_MSG_BLACKHOLE_info);
- OVERWRITE_INFO(target->block_info.bh, &stg_IND_info);
- raiseAsync(cap, target, msg->exception, rtsFalse, NULL);
- return THROWTO_SUCCESS;
+ if (target->flags & TSO_BLOCKEX) {
+ // BlockedOnBlackHole is not interruptible.
+ blockedThrowTo(cap,target,msg);
+ return THROWTO_BLOCKED;
+ } else {
+ // Revoke the message by replacing it with IND. We're not
+ // locking anything here, so we might still get a TRY_WAKEUP
+ // message from the owner of the blackhole some time in the
+ // future, but that doesn't matter.
+ ASSERT(target->block_info.bh->header.info == &stg_MSG_BLACKHOLE_info);
+ OVERWRITE_INFO(target->block_info.bh, &stg_IND_info);
+ raiseAsync(cap, target, msg->exception, rtsFalse, NULL);
+ return THROWTO_SUCCESS;
+ }
}
case BlockedOnSTM:
return THROWTO_SUCCESS;
}
+ case BlockedOnCCall_Interruptible:
+#ifdef THREADED_RTS
+ {
+ Task *task = NULL;
+ // walk suspended_ccalls to find the correct worker thread
+ InCall *incall;
+ for (incall = cap->suspended_ccalls; incall != NULL; incall = incall->next) {
+ if (incall->suspended_tso == target) {
+ task = incall->task;
+ break;
+ }
+ }
+ if (task != NULL) {
+ raiseAsync(cap, target, msg->exception, rtsFalse, NULL);
+ interruptWorkerTask(task);
+ return THROWTO_SUCCESS;
+ } else {
+ debugTraceCap(DEBUG_sched, cap, "throwTo: could not find worker thread to kill");
+ }
+ // fall to next
+ }
+#endif
case BlockedOnCCall:
- case BlockedOnCCall_NoUnblockExc:
blockedThrowTo(cap,target,msg);
return THROWTO_BLOCKED;
// top of the CATCH_FRAME ready to enter.
//
{
-#ifdef PROFILING
StgCatchFrame *cf = (StgCatchFrame *)frame;
-#endif
StgThunk *raise;
if (exception == NULL) break;
* a surprise exception before we get around to executing the
* handler.
*/
- tso->flags |= TSO_BLOCKEX | TSO_INTERRUPTIBLE;
+ tso->flags |= TSO_BLOCKEX;
+ if ((cf->exceptions_blocked & TSO_INTERRUPTIBLE) == 0) {
+ tso->flags &= ~TSO_INTERRUPTIBLE;
+ } else {
+ tso->flags |= TSO_INTERRUPTIBLE;
+ }
/* Put the newly-built THUNK on top of the stack, ready to execute
* when the thread restarts.