/* -----------------------------------------------------------------------------
- * $Id: Schedule.c,v 1.34 1999/11/18 12:10:29 sewardj Exp $
+ * $Id: Schedule.c,v 1.38 1999/12/01 16:13:25 simonmar Exp $
*
* (c) The GHC Team, 1998-1999
*
#include "StgMiscClosures.h"
#include "Storage.h"
#include "Evaluator.h"
+#include "Exception.h"
#include "Printer.h"
#include "Main.h"
#include "Signals.h"
void
initThread(StgTSO *tso, nat stack_size)
{
- SET_INFO(tso,&TSO_info);
+ SET_HDR(tso, &TSO_info, CCS_MAIN);
tso->whatNext = ThreadEnterGHC;
/* tso->id needs to be unique. For now we use a heavyweight mutex to
RELEASE_LOCK(&sched_mutex);
tso->why_blocked = NotBlocked;
+ tso->blocked_exceptions = NULL;
tso->splim = (P_)&(tso->stack) + RESERVED_STACK_WORDS;
tso->stack_size = stack_size;
case BlockedOnMVar:
fprintf(stderr,"blocked on an MVar");
break;
+ case BlockedOnException:
+ fprintf(stderr,"blocked on delivering an exception to thread %d",
+ tso->block_info.tso->id);
+ break;
case BlockedOnBlackHole:
fprintf(stderr,"blocked on a black hole");
break;
barf("unblockThread (BLACKHOLE): TSO not found");
}
+ case BlockedOnException:
+ {
+ StgTSO *target = tso->block_info.tso;
+
+ ASSERT(get_itbl(target)->type == TSO);
+ ASSERT(target->blocked_exceptions != NULL);
+
+ last = &target->blocked_exceptions;
+ for (t = target->blocked_exceptions; t != END_TSO_QUEUE;
+ last = &t->link, t = t->link) {
+ ASSERT(get_itbl(t)->type == TSO);
+ if (t == tso) {
+ *last = tso->link;
+ goto done;
+ }
+ }
+ barf("unblockThread (Exception): TSO not found");
+ }
+
case BlockedOnDelay:
case BlockedOnRead:
case BlockedOnWrite:
ap->fun = cf->handler;
ap->payload[0] = (P_)exception;
- /* sp currently points to the word above the CATCH_FRAME on the
- * stack. Replace the CATCH_FRAME with a pointer to the new handler
- * application.
+ /* sp currently points to the word above the CATCH_FRAME on the stack.
*/
sp += sizeofW(StgCatchFrame);
- sp[0] = (W_)ap;
tso->su = cf->link;
+
+ /* Restore the blocked/unblocked state for asynchronous exceptions
+ * at the CATCH_FRAME.
+ *
+ * If exceptions were unblocked at the catch, arrange that they
+ * are unblocked again after executing the handler by pushing an
+ * unblockAsyncExceptions_ret stack frame.
+ */
+ if (!cf->exceptions_blocked) {
+ *(sp--) = (W_)&unblockAsyncExceptionszh_ret_info;
+ }
+
+ /* Ensure that async exceptions are blocked when running the handler.
+ */
+ if (tso->blocked_exceptions == NULL) {
+ tso->blocked_exceptions = END_TSO_QUEUE;
+ }
+
+ /* Put the newly-built PAP on top of the stack, ready to execute
+ * when the thread restarts.
+ */
+ sp[0] = (W_)ap;
tso->sp = sp;
tso->whatNext = ThreadEnterGHC;
return;