diff --git a/data/apps/red.lua b/data/apps/red.lua index f3ce41d..2d6678e 100644 --- a/data/apps/red.lua +++ b/data/apps/red.lua @@ -608,6 +608,7 @@ win - pseudo acme win (just make &1' end - local f = io.popen(prog, "r") - if not f then return end - local p = w:run(function() --- w:tail() - local num = 1 --- local cur = w:cur() + local p = thread.start(function() + local prog = thread:read() + local f = io.popen(prog, "r") + if f then + for l in f:lines() do + thread:write(l) + end + f:close() + end + thread:write '\1eof' + end, prog, tmp) + local r = w:run(function() w:history 'start' - for l in f:lines() do - w.buf:input(l ..'\n') - num = num + 1 - if num % 100 == 0 then - coroutine.yield() + local l + p:write(prog) + while l ~= '\1eof' do + while p:poll() do + l = p:read() + if l == '\1eof' then + break + end + w.buf:input(l..'\n') end + coroutine.yield() end - f:close() if sh then - w:input("$ ") + w:input '$ ' end w:history 'end' --- w.buf:setsel(cur, w:cur()) --- w:cur(cur) if tmp then os.remove(tmp) end end) - p.kill = function() - if f then - f:close() - f = nil - if tmp then - os.remove(tmp) - end - end + r.kill = function() + p:kill() end end @@ -279,6 +281,7 @@ function win_newline(self) if not r then self.buf:input("Error\n") end + self.buf:input '$ ' else pipe(self, t, false, true) end diff --git a/data/lib/red/win.lua b/data/lib/red/win.lua index 3b1a25d..c3f739d 100644 --- a/data/lib/red/win.lua +++ b/data/lib/red/win.lua @@ -85,8 +85,7 @@ function win:killproc() self.killed = true for _, v in ipairs(self.co) do if v.kill then - debug.sethook(v[1], v.kill, 'l') - coroutine.resume(v[1]) + v.kill() end end self.co = {} diff --git a/src/thread.c b/src/thread.c index af65cf5..c8581b3 100644 --- a/src/thread.c +++ b/src/thread.c @@ -443,7 +443,7 @@ thread_stop(lua_State *L) int haschild; if (!chan) return 0; - printf("Thread stop\n"); +// printf("Thread stop\n"); MutexLock(chan->m); chan->peers[0].L = NULL; haschild = !!chan->peers[1].L; @@ -459,12 +459,34 @@ thread_stop(lua_State *L) return 0; } +static int +thread_kill(lua_State *L) +{ + struct lua_thread *thr = (struct lua_thread*)luaL_checkudata(L, 1, "thread metatable"); + struct lua_channel *chan = thr->chan; + int haschild; + if (!chan) + return 0; +// printf("Thread kill\n"); + MutexLock(chan->m); + chan->peers[0].L = NULL; + haschild = !!chan->peers[1].L; + MutexUnlock(chan->m); + if (haschild) { + SemPost(chan->peers[1].sem); + chan->peers[1].L = NULL; + chan->used = 0; + } + return 0; +} + static const luaL_Reg thread_mt[] = { { "wait", thread_wait }, { "write", thread_write }, { "read", thread_read }, { "poll", thread_poll }, { "err", thread_err }, + { "kill", thread_kill }, { "__gc", thread_stop }, { NULL, NULL } };