X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2FRtsAPI.c;h=d0bdead1c9b36181ada4c01de354e1e4085e1a35;hb=0e4eef1e5c326750d1b94c9b365c0b3fab19e611;hp=716b4a2f2b028fb9c699f25df89bdd985cca7090;hpb=6015a94f9108a502150565577b66c23650796639;p=ghc-hetmet.git diff --git a/rts/RtsAPI.c b/rts/RtsAPI.c index 716b4a2..d0bdead 100644 --- a/rts/RtsAPI.c +++ b/rts/RtsAPI.c @@ -51,7 +51,7 @@ rts_mkInt8 (Capability *cap, HsInt8 i) StgClosure *p = (StgClosure *)allocateLocal(cap,CONSTR_sizeW(0,1)); SET_HDR(p, I8zh_con_info, CCS_SYSTEM); /* Make sure we mask out the bits above the lowest 8 */ - p->payload[0] = (StgClosure *)(StgInt)((unsigned)i & 0xff); + p->payload[0] = (StgClosure *)(StgInt)i; return p; } @@ -61,7 +61,7 @@ rts_mkInt16 (Capability *cap, HsInt16 i) StgClosure *p = (StgClosure *)allocateLocal(cap,CONSTR_sizeW(0,1)); SET_HDR(p, I16zh_con_info, CCS_SYSTEM); /* Make sure we mask out the relevant bits */ - p->payload[0] = (StgClosure *)(StgInt)((unsigned)i & 0xffff); + p->payload[0] = (StgClosure *)(StgInt)i; return p; } @@ -70,7 +70,7 @@ rts_mkInt32 (Capability *cap, HsInt32 i) { StgClosure *p = (StgClosure *)allocateLocal(cap,CONSTR_sizeW(0,1)); SET_HDR(p, I32zh_con_info, CCS_SYSTEM); - p->payload[0] = (StgClosure *)(StgInt)((unsigned)i & 0xffffffff); + p->payload[0] = (StgClosure *)(StgInt)i; return p; } @@ -491,6 +491,9 @@ rts_evalStableIO (Capability *cap, HsStablePtr s, /*out*/HsStablePtr *ret) p = (StgClosure *)deRefStablePtr(s); tso = createStrictIOThread(cap, RtsFlags.GcFlags.initialStkSize, p); + // async exceptions are always blocked by default in the created + // thread. See #1048. + tso->flags |= TSO_BLOCKEX | TSO_INTERRUPTIBLE; cap = scheduleWaitThread(tso,&r,cap); stat = rts_getSchedStatus(cap); @@ -584,18 +587,20 @@ rts_unlock (Capability *cap) task = cap->running_task; ASSERT_FULL_CAPABILITY_INVARIANTS(cap,task); - // slightly delicate ordering of operations below, pay attention! - - // We are no longer a bound task/thread. This is important, - // because the GC can run when we release the Capability below, - // and we don't want it to treat this as a live TSO pointer. - task->tso = NULL; - // Now release the Capability. With the capability released, GC // may happen. NB. does not try to put the current Task on the // worker queue. - releaseCapability(cap); + // NB. keep cap->lock held while we call boundTaskExiting(). This + // is necessary during shutdown, where we want the invariant that + // after shutdownCapability(), all the Tasks associated with the + // Capability have completed their shutdown too. Otherwise we + // could have boundTaskExiting()/workerTaskStop() running at some + // random point in the future, which causes problems for + // freeTaskManager(). + ACQUIRE_LOCK(&cap->lock); + releaseCapability_(cap,rtsFalse); // Finally, we can release the Task to the free list. boundTaskExiting(task); + RELEASE_LOCK(&cap->lock); }