static void tek_lib_visual_io_task(struct TTask *task) { struct TExecBase *TExecBase = TGetExecBase(task); struct IOData *iodata = TGetTaskData(task); TEKVisual *vis = iodata->vis; TIMSG *imsg; TUINT sig; #if defined(ENABLE_FILENO) || defined(ENABLE_DGRAM) char buf[256]; fd_set rset; #endif do { #if defined(ENABLE_FILENO) || defined(ENABLE_DGRAM) FD_ZERO(&rset); FD_SET(iodata->fd_pipe[0], &rset); #endif #if defined(ENABLE_FILENO) if (iodata->fd_stdin != -1) FD_SET(iodata->fd_stdin, &rset); #endif #if defined(ENABLE_DGRAM) FD_SET(iodata->fd_dgram, &rset); #endif #if defined(ENABLE_FILENO) || defined(ENABLE_DGRAM) if (select(iodata->fdmax, &rset, NULL, NULL, NULL) > 0) { int nbytes = 0; /* consume signal: */ if (FD_ISSET(iodata->fd_pipe[0], &rset)) { ioctl(iodata->fd_pipe[0], FIONREAD, &nbytes); if (nbytes > 0) if (read(iodata->fd_pipe[0], buf, TMIN(sizeof(buf), (size_t) nbytes)) != nbytes) TDBPRINTF(TDB_ERROR,("Error reading from selfpipe\n")); } #if defined(ENABLE_FILENO) /* stdin line reader: */ if (iodata->fd_stdin >= 0 && FD_ISSET(iodata->fd_stdin, &rset)) { if (ioctl(iodata->fd_stdin, FIONREAD, &nbytes) == 0) { if (nbytes == 0) iodata->fd_stdin = -1; /* stop processing */ else { char *line; size_t len; visual_io_reader_addbytes(&iodata->linereader, nbytes); while (visual_io_readline(&iodata->linereader, &line, &len)) { if (getusermsg(vis, &imsg, TITYPE_USER, len)) { memcpy((void *) (imsg + 1), line, len); TPutMsg(vis->vis_IMsgPort, TNULL, &imsg->timsg_Node); } } } } else iodata->fd_stdin = -1; /* stop processing */ } #endif #if defined(ENABLE_DGRAM) if (iodata->fd_dgram >= 0 && FD_ISSET(iodata->fd_dgram, &rset)) { char umsg[IOMAXMSGSIZE]; TIMSG *imsg; ssize_t len = recv(iodata->fd_dgram, umsg, sizeof umsg, 0); if (len >= 0 && getusermsg(vis, &imsg, TITYPE_USER, len)) { memcpy((void *) (imsg + 1), umsg, len); TPutMsg(vis->vis_IMsgPort, TNULL, &imsg->timsg_Node); } } #endif } sig = TSetSignal(0, TTASK_SIG_ABORT | TTASK_SIG_USER); #else sig = TWait(TTASK_SIG_ABORT | TTASK_SIG_USER); #endif if (sig & TTASK_SIG_USER) { TAPTR msg, uport = TGetUserPort(TNULL); while ((msg = TGetMsg(uport))) { TSIZE len = TGetSize(msg); /* repackage into user input message */ if (getusermsg(vis, &imsg, TITYPE_USER, len)) { memcpy((void *) (imsg + 1), msg, len); TPutMsg(vis->vis_IMsgPort, TNULL, &imsg->timsg_Node); } TAckMsg(msg); } } } while (!(sig & TTASK_SIG_ABORT)); tek_lib_visual_io_exit(task); }
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; }