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; }
static TBOOL tek_lib_exec_sendtaskport(struct TTask *task, const char *portname, const char *buf, size_t len) { struct TExecBase *TExecBase = TGetExecBase(task); char atomname[256]; TAPTR atom; TBOOL success = TFALSE; sprintf(atomname, "msgport.%s.%p", portname, task); atom = TLockAtom(atomname, TATOMF_SHARED | TATOMF_NAME); if (atom) { TAPTR imsgport = (TAPTR) TGetAtomData(atom); if (imsgport) { TAPTR msg = TAllocMsg0(len); if (msg) { memcpy(msg, buf, len); TPutMsg(imsgport, TNULL, msg); success = TTRUE; } } TUnlockAtom(atom, TATOMF_KEEP); } return success; }
static void tek_lib_visual_io_exit(struct TTask *task) { struct TExecBase *TExecBase = TGetExecBase(task); struct IOData *iodata = TGetTaskData(task); #if defined(ENABLE_FILENO) || defined(ENABLE_DGRAM) int i; for (i = 0; i < 2; ++i) if (iodata->fd_pipe[i] != -1) close(iodata->fd_pipe[i]); #if defined(ENABLE_DGRAM) if (iodata->fd_dgram != -1) close(iodata->fd_dgram); #endif #if defined(ENABLE_FILENO) visual_io_reader_exit(&iodata->linereader); #endif #endif TLockAtom(iodata->atomname, TATOMF_NAME | TATOMF_DESTROY); }
static int tek_lib_exec_base_gc(lua_State *L) { struct LuaExecTask *lexec = (struct LuaExecTask *)luaL_checkudata(L, 1, TEK_LIB_EXEC_CLASSNAME); struct TExecBase *TExecBase = lexec->exec; if (TExecBase) { #if defined(ENABLE_TASKS) TAPTR atom = TLockAtom(TEK_LIB_BASETASK_ATOMNAME, TATOMF_NAME); TUnlockAtom(atom, TATOMF_DESTROY); if (lexec->parent == TNULL) { /* free shared state */ TFree(lexec->shared); } #endif TDestroy((struct THandle *) lexec->task); lexec->exec = TNULL; } return 0; }
static TAPTR tek_lib_exec_locktask(struct TExecBase *TExecBase, const char *name, TAPTR *ref) { if (name && strcmp(name, "*p") != 0) { char atomname[TEK_LIB_TASKNAME_LEN]; tek_lib_exec_taskname(atomname, name); *ref = TLockAtom(atomname, TATOMF_NAME | TATOMF_SHARED); if (*ref) return (TAPTR) TGetAtomData(*ref); } else { struct LuaExecTask *parent = getparent(TExecBase); *ref = TNULL; if (parent) return parent->task; } return TNULL; }
static TBOOL tek_lib_exec_init_link_to_parent(lua_State *L, struct LuaExecTask *lexec) { struct TExecBase *TExecBase = lexec->exec; TAPTR atom; /* task's userdata initially contains a pointer to ** childtask-userdata in parent Lua state */ struct LuaExecChild *ctx = TGetTaskData(TNULL); /* now relink to own task */ TSetTaskData(TNULL, lexec); lexec->parent = ctx ? ctx->parent : TNULL; if (ctx && ctx->taskname) { /* child context */ strcpy(lexec->atomname, ctx->atomname); lexec->taskname = lexec->atomname + TEK_LIB_TASK_ATOMNAME_OFFSET; lexec->shared = ctx->parent->shared; } else { /* root context */ lexec->taskname = tek_lib_exec_taskname(lexec->atomname, "main"); lexec->shared = TAlloc(TNULL, sizeof(struct SharedState)); if (lexec->shared == TNULL) return TFALSE; } atom = TLockAtom(TEK_LIB_BASETASK_ATOMNAME, TATOMF_CREATE | TATOMF_NAME | TATOMF_TRY); if (atom) { TSetAtomData(atom, (TTAG) lexec->task); TUnlockAtom(atom, TATOMF_KEEP); } return TTRUE; }
static TBOOL tek_lib_visual_io_init(struct TTask *task) { struct TExecBase *TExecBase = TGetExecBase(task); struct IOData *iodata = TGetTaskData(task); #if defined(ENABLE_FILENO) || defined(ENABLE_DGRAM) TEKVisual *vis = iodata->vis; iodata->fd_pipe[0] = -1; iodata->fd_pipe[1] = -1; iodata->fdmax = 0; TInitHook(&iodata->mphook, tek_lib_visual_io_mphookfunc, iodata); TSetPortHook(TGetUserPort(TNULL), &iodata->mphook); #endif #if defined(ENABLE_FILENO) int fd = vis->vis_IOFileNo; iodata->fd_stdin = fd == -1 ? STDIN_FILENO : fd; visual_io_reader_init(&iodata->linereader, iodata->fd_stdin, IOMAXMSGSIZE); iodata->fdmax = TMAX(iodata->fdmax, iodata->fd_stdin); #endif #if defined(ENABLE_DGRAM) iodata->fd_dgram = socket(PF_INET, SOCK_DGRAM, 0); if (iodata->fd_dgram != -1) { int reuse = 1; setsockopt(iodata->fd_dgram, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, sizeof(reuse)); struct sockaddr_in addr; memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(ENABLE_DGRAM_ADDR); addr.sin_port = htons(ENABLE_DGRAM); if (bind(iodata->fd_dgram, (struct sockaddr *) &addr, sizeof addr) == -1) { close(iodata->fd_dgram); iodata->fd_dgram = -1; } } if (iodata->fd_dgram == -1) { tek_lib_visual_io_exit(task); return TFALSE; } iodata->fdmax = TMAX(iodata->fdmax, iodata->fd_dgram); #endif #if defined(ENABLE_FILENO) || defined(ENABLE_DGRAM) if (pipe(iodata->fd_pipe) != 0) return TFALSE; iodata->fdmax = TMAX(iodata->fdmax, iodata->fd_pipe[0]) + 1; #endif TAPTR atom = TLockAtom(iodata->atomname, TATOMF_CREATE | TATOMF_NAME); if (atom) { TSetAtomData(atom, (TTAG) TGetUserPort(TNULL)); TUnlockAtom(atom, TATOMF_KEEP); } return TTRUE; }