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;
}
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;
}
{
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;
}
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);
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);
}