static THOOKENTRY TTAG tek_lib_exec_run_dispatch(struct THook *hook, TAPTR task, TTAG msg) { struct LuaExecChild *ctx = hook->thk_Data; struct TExecBase *TExecBase = ctx->exec; switch (msg) { case TMSG_INITTASK: { TAPTR atom; if (!ctx->taskname) { sprintf(ctx->atomname, "task.task: %p", task); ctx->taskname = ctx->atomname + TEK_LIB_TASK_ATOMNAME_OFFSET; } atom = TLockAtom(ctx->atomname, TATOMF_CREATE | TATOMF_NAME | TATOMF_TRY); if (!atom) return TFALSE; TSetAtomData(atom, (TTAG) task); TUnlockAtom(atom, TATOMF_KEEP); return TTRUE; } case TMSG_RUNTASK: { struct LuaExecTask *parent = ctx->parent; TUINT sig = TTASK_SIG_CHLD; ctx->task = TFindTask(TNULL); lua_pushcfunction(ctx->L, &tek_lib_exec_runchild); lua_pushlightuserdata(ctx->L, ctx); ctx->status = lua_pcall(ctx->L, 1, 1, 0); TDBPRINTF(TDB_TRACE,("pcall2 ctx->status=%d\n", ctx->status)); report(ctx->L, ctx->status); lua_close(ctx->L); if (ctx->status) sig |= TTASK_SIG_ABORT; TSignal(parent->task, sig); if (ctx->taskname) { TAPTR atom = TLockAtom(ctx->atomname, TATOMF_NAME); TUnlockAtom(atom, TATOMF_DESTROY); } break; } } return 0; }
TLIBAPI struct TModule *TNewInstance(struct TModule *mod, TSIZE possize, TSIZE negsize) { struct TExecBase *TExecBase = TGetExecBase(mod); TAPTR inst = TAlloc(TNULL, possize + negsize); if (inst) { TSIZE size = TMIN(((struct TModule *) mod)->tmd_NegSize, negsize); inst = (TINT8 *) inst + negsize; if (size > 0) TCopyMem((TINT8 *) mod - size, (TINT8 *) inst - size, size); size = TMIN(((struct TModule *) mod)->tmd_PosSize, possize); TCopyMem(mod, inst, size); ((struct TModule *) inst)->tmd_PosSize = possize; ((struct TModule *) inst)->tmd_NegSize = negsize; ((struct TModule *) inst)->tmd_InitTask = TFindTask(TNULL); } return inst; }
LOCAL TBOOL tek_lib_visual_io_open(TEKVisual *vis) { struct TExecBase *TExecBase = vis->vis_ExecBase; struct IOData *iodata = TAlloc(TNULL, sizeof(struct IOData)); if (iodata) { TTAGITEM tags[2]; sprintf(iodata->atomname, "msgport.ui.%p", TFindTask(TNULL)); iodata->vis = vis; vis->vis_IOData = iodata; tags[0].tti_Tag = TTask_UserData; tags[0].tti_Value = (TTAG) iodata; tags[1].tti_Tag = TTAG_DONE; struct THook taskhook; TInitHook(&taskhook, tek_lib_visual_io_dispatch, TNULL); vis->vis_IOTask = TCreateTask(&taskhook, tags); if (vis->vis_IOTask) return TTRUE; TFree(iodata); vis->vis_IOData = TNULL; } return TFALSE; }
static int tek_lib_exec_child_sigjoin(lua_State *L, TUINT sig, TBOOL sigparent, TBOOL do_results) { struct LuaExecChild *ctx = luaL_checkudata(L, 1, TEK_LIB_TASK_CLASSNAME); struct TExecBase *TExecBase = ctx->exec; struct TTask *self = TFindTask(TNULL), *task = ctx->task; union TTaskRequest *req = &self->tsk_Request; TBOOL abort = TFALSE; int nres = 0; if (!task) return 0; TDBPRINTF(TDB_TRACE,("child_join sig=%d sigparent=%d\n", sig, sigparent)); /* signal task */ TSignal(task, sig); /* prepare destroy request */ self->tsk_ReqCode = TTREQ_DESTROYTASK; req->trq_Task.trt_Task = task; /* send to exec */ TPutMsg(TExecBase->texb_ExecPort, &self->tsk_SyncPort, self); for (;;) { /* wait for return of request or receiving abort ourselves: */ TUINT sig = TWait(TTASK_SIG_SINGLE | TTASK_SIG_ABORT); if (sig & TTASK_SIG_SINGLE) break; if (sig & TTASK_SIG_ABORT) { /* forward to child task */ TSignal(task, TTASK_SIG_ABORT); if (sigparent) { /* also forward to own parent task */ struct LuaExecTask *parent = getparent(TExecBase); if (parent) TSignal(parent->task, TTASK_SIG_ABORT); abort = TTRUE; } } } /* take delivery of replied destroy request */ TGetMsg(&self->tsk_SyncPort); /* free task */ TFreeTask(task); ctx->task = TNULL; tek_lib_exec_freectxargs(ctx); if (!abort && do_results) { int i; nres = ctx->numres + 1; lua_pushboolean(L, ctx->luastatus == 0); for (i = 0; i < ctx->numres; ++i) lua_pushlstring(L, ctx->results[i].arg, ctx->results[i].len); } tek_lib_exec_freeargs(TExecBase, ctx->results, ctx->numres); luaL_unref(L, lua_upvalueindex(1), ctx->ref); if (abort) luaL_error(L, "received abort signal"); return nres; }