// give this Capability to the appropriate Task.
if (!emptyRunQueue(cap) && cap->run_queue_hd->bound) {
// Make sure we're not about to try to wake ourselves up
- ASSERT(task != cap->run_queue_hd->bound);
+ // ASSERT(task != cap->run_queue_hd->bound);
+ // assertion is false: in schedule() we force a yield after
+ // ThreadBlocked, but the thread may be back on the run queue
+ // by now.
task = cap->run_queue_hd->bound;
giveCapabilityToTask(cap,task);
return;
"thread(s) are involved in foreign calls, yielding");
cap->running_task = NULL;
RELEASE_LOCK(&cap->lock);
+ // The IO manager thread might have been slow to start up,
+ // so the first attempt to kill it might not have
+ // succeeded. Just in case, try again - the kill message
+ // will only be sent once.
+ //
+ // To reproduce this deadlock: run ffi002(threaded1)
+ // repeatedly on a loaded machine.
+ ioManagerDie();
yieldThread();
continue;
}
-
+
traceEventShutdown(cap);
RELEASE_LOCK(&cap->lock);
break;