diff options
Diffstat (limited to 'rts/Schedule.c')
-rw-r--r-- | rts/Schedule.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/rts/Schedule.c b/rts/Schedule.c index b9b15811c9..4fe18fa769 100644 --- a/rts/Schedule.c +++ b/rts/Schedule.c @@ -942,6 +942,7 @@ scheduleDetectDeadlock (Capability **pcap, Task *task) */ if (SEQ_CST_LOAD(&recent_activity) != ACTIVITY_INACTIVE) return; #endif + if (task->incall->tso && task->incall->tso->why_blocked == BlockedOnIOCompletion) return; debugTrace(DEBUG_sched, "deadlocked, forcing major GC..."); @@ -979,6 +980,31 @@ scheduleDetectDeadlock (Capability **pcap, Task *task) return; } #endif + +#if !defined(THREADED_RTS) + /* Probably a real deadlock. Send the current main thread the + * Deadlock exception. + */ + if (task->incall->tso) { + switch (task->incall->tso->why_blocked) { + case BlockedOnSTM: + case BlockedOnBlackHole: + case BlockedOnMsgThrowTo: + case BlockedOnMVar: + case BlockedOnMVarRead: + throwToSingleThreaded(cap, task->incall->tso, + (StgClosure *)nonTermination_closure); + return; + case BlockedOnIOCompletion: + /* We're blocked waiting for an external I/O call, let's just + chill for a bit. */ + return; + default: + barf("deadlock: main thread blocked in a strange way"); + } + } + return; +#endif } } @@ -3192,6 +3218,11 @@ resurrectThreads (StgTSO *threads) throwToSingleThreaded(cap, tso, (StgClosure *)blockedIndefinitelyOnSTM_closure); break; + case BlockedOnIOCompletion: + /* I/O Ports may not be reachable by the GC as they may be getting + * notified by the RTS. As such this call should be treated as if + * it is masking the exception. */ + continue; case NotBlocked: /* This might happen if the thread was blocked on a black hole * belonging to a thread that we've just woken up (raiseAsync |