Skip to content

Commit

Permalink
red: use rein threads for pipe
Browse files Browse the repository at this point in the history
  • Loading branch information
hugeping committed Sep 15, 2023
1 parent 7cc3611 commit d214255
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 26 deletions.
10 changes: 10 additions & 0 deletions data/apps/red.lua
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,7 @@ win - pseudo acme win (just make <cmd for all input lines)
end

function mainmenu.cmd:Exit()
self.frame:killproc()
local w = self.frame:dirty()
if w then
w.frame:err("File %q is not saved!", w.buf.fname)
Expand Down Expand Up @@ -763,6 +764,14 @@ end

local main = mainwin:new(mainmenu)

function main:killproc()
for fr in main:for_win() do
for w in fr:for_win() do
w:killproc()
end
end
end

function mainwin:open_err(n)
n = n or "+Errors"
local w = self:win_by_name(n)
Expand Down Expand Up @@ -925,5 +934,6 @@ end
if conf.save_dump then
mainmenu.cmd.Exit(mainmenu)
end

mixer.done()
print "Quit..."
49 changes: 26 additions & 23 deletions data/lib/red/proc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -182,39 +182,41 @@ local function pipe(w, prog, tmp, sh)
if PLATFORM ~= 'Windows' then
prog = '( ' ..prog .. ' ) </dev/null 2>&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

Expand Down Expand Up @@ -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
Expand Down
3 changes: 1 addition & 2 deletions data/lib/red/win.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {}
Expand Down
24 changes: 23 additions & 1 deletion src/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 }
};
Expand Down

0 comments on commit d214255

Please sign in to comment.