cap = (Capability *)((void *)((unsigned char*)resumeThread(tok) - STG_FIELD_OFFSET(Capability,r)));
LOAD_STACK_POINTERS;
+ if (Sp[0] == (W_)&stg_enter_info) {
+ // Sp got clobbered due to an exception; so we should
+ // go run it instead.
+ Sp++;
+ goto eval;
+ }
+
// Re-load the pointer to the BCO from the RET_DYN frame,
// it might have moved during the call. Also reload the
// pointers to the components of the BCO.
}
}
if (task != NULL) {
- raiseAsync(cap, target, msg->exception, rtsFalse, NULL);
- interruptWorkerTask(task);
- return THROWTO_SUCCESS;
+ blockedThrowTo(cap, target, msg);
+ if (!((target->flags & TSO_BLOCKEX) && ((target->flags & TSO_INTERRUPTIBLE) == 0))) {
+ interruptWorkerTask(task);
+ }
+ return THROWTO_BLOCKED;
} else {
debugTraceCap(DEBUG_sched, cap, "throwTo: could not find worker thread to kill");
}
goto done;
#endif
+ case BlockedOnCCall_Interruptible:
+ case BlockedOnCCall:
+ // ccall shouldn't be put on the run queue, because whenever
+ // we raise an exception for such a blocked thread, it's only
+ // when we're /exiting/ the call.
+ tso->why_blocked = NotBlocked;
+ return;
+
default:
barf("removeFromQueues: %d", tso->why_blocked);
}
if ((tso->flags & TSO_BLOCKEX) == 0) {
// avoid locking the TSO if we don't have to
if (tso->blocked_exceptions != END_BLOCKED_EXCEPTIONS_QUEUE) {
- awakenBlockedExceptionQueue(cap,tso);
+ maybePerformBlockedException(cap,tso);
}
}
// if the thread is not masking exceptions but there are
// pending exceptions on its queue, then something has gone
// wrong. However, pending exceptions are OK if there is an
- // uninterruptible FFI call.
+ // FFI call.
ASSERT(t->blocked_exceptions == END_BLOCKED_EXCEPTIONS_QUEUE
|| t->why_blocked == BlockedOnCCall
+ || t->why_blocked == BlockedOnCCall_Interruptible
|| (t->flags & TSO_BLOCKEX));
if (tmp == NULL) {