close handles on procs in reverse order

also explicitly close stdout in cat. proc closes it, but this is cleaner
This commit is contained in:
payonel 2020-04-28 10:36:25 -07:00
parent b117cbf89b
commit ad5443c415
9 changed files with 46 additions and 45 deletions

View File

@ -35,3 +35,5 @@ for i = 1, #args do
end end
end end
end end
io.stdout:close()

View File

@ -45,7 +45,7 @@ local cols =
{"THREADS", function(_,p) {"THREADS", function(_,p)
-- threads are handles with mt.close == thread.waitForAll -- threads are handles with mt.close == thread.waitForAll
local count = 0 local count = 0
for h in pairs(p.data.handles) do for _,h in ipairs(p.data.handles) do
local mt = getmetatable(h) local mt = getmetatable(h)
if mt and mt.__status then if mt and mt.__status then
count = count + 1 count = count + 1
@ -55,7 +55,7 @@ local cols =
end}, end},
{"PARENT", function(_,p) {"PARENT", function(_,p)
for _,process_info in pairs(process.list) do for _,process_info in pairs(process.list) do
for handle in pairs(process_info.data.handles) do for i,handle in ipairs(process_info.data.handles) do
local mt = getmetatable(handle) local mt = getmetatable(handle)
if mt and mt.__status then if mt and mt.__status then
if mt.process == p then if mt.process == p then
@ -67,12 +67,7 @@ local cols =
return thread_id(nil, p.parent) return thread_id(nil, p.parent)
end}, end},
{"HANDLES", function(_, p) {"HANDLES", function(_, p)
local count = 0 local count = #p.data.handles
for _,closure in pairs(p.data.handles) do
if closure then
count = count + 1
end
end
return count == 0 and "-" or tostring(count) return count == 0 and "-" or tostring(count)
end}, end},
{"CMD", function(_,p) return p.command end}, {"CMD", function(_,p) return p.command end},

View File

@ -76,7 +76,7 @@ local fs_open = fs.open
fs.open = function(...) fs.open = function(...)
local fs_open_result = table.pack(fs_open(...)) local fs_open_result = table.pack(fs_open(...))
if fs_open_result[1] then if fs_open_result[1] then
process.closeOnExit(fs_open_result[1]) process.addHandle(fs_open_result[1])
end end
return table.unpack(fs_open_result, 1, fs_open_result.n) return table.unpack(fs_open_result, 1, fs_open_result.n)
end end

View File

@ -166,7 +166,7 @@ function buffer:write(...)
if self.bufferMode == "no" then if self.bufferMode == "no" then
result, reason = self.stream:write(arg) result, reason = self.stream:write(arg)
else else
result, reason = self:buffered_write(arg) result, reason = buffer.buffered_write(self, arg)
end end
if not result then if not result then

View File

@ -2,6 +2,7 @@ local text = require("text")
local tx = require("transforms") local tx = require("transforms")
local unicode = require("unicode") local unicode = require("unicode")
local process = require("process") local process = require("process")
local buffer = require("buffer")
-- separate string value into an array of words delimited by whitespace -- separate string value into an array of words delimited by whitespace
-- groups by quotes -- groups by quotes
@ -179,9 +180,7 @@ function text.internal.reader(txt, mode)
return true return true
end, end,
}, {__index=text.internal.stream_base((mode or ""):match("b"))}) }, {__index=text.internal.stream_base((mode or ""):match("b"))})
process.closeOnExit(reader) return process.addHandle(buffer.new((mode or "r"):match("[rb]+"), reader))
return require("buffer").new((mode or "r"):match("[rb]+"), reader)
end end
function text.internal.writer(ostream, mode, append_txt) function text.internal.writer(ostream, mode, append_txt)
@ -221,9 +220,7 @@ function text.internal.writer(ostream, mode, append_txt)
return true return true
end, end,
}, {__index=text.internal.stream_base((mode or ""):match("b"))}) }, {__index=text.internal.stream_base((mode or ""):match("b"))})
process.closeOnExit(writer) return process.addHandle(buffer.new((mode or "w"):match("[awb]+"), writer))
return require("buffer").new((mode or "w"):match("[awb]+"), writer)
end end
function text.detab(value, tabWidth) function text.detab(value, tabWidth)

View File

@ -70,14 +70,12 @@ function require(module)
end end
function package.delay(lib, file) function package.delay(lib, file)
local mt = { local mt = {}
__index = function(tbl, key) function mt.__index(tbl, key)
setmetatable(lib, nil) mt.__index = nil
setmetatable(lib.internal or {}, nil)
dofile(file) dofile(file)
return tbl[key] return tbl[key]
end end
}
if lib.internal then if lib.internal then
setmetatable(lib.internal, mt) setmetatable(lib.internal, mt)
end end

View File

@ -133,7 +133,7 @@ function pipe.buildPipeChain(progs)
local piped_stream local piped_stream
if i < #progs then if i < #progs then
local handle = setmetatable({buffer = ""}, {__index = pipe_stream}) local handle = setmetatable({buffer = ""}, {__index = pipe_stream})
process.closeOnExit(handle, proc) process.addHandle(handle, proc)
piped_stream = buffer.new("rw", handle) piped_stream = buffer.new("rw", handle)
piped_stream:setvbuf("no", 1024) piped_stream:setvbuf("no", 1024)
pio[1] = piped_stream pio[1] = piped_stream

View File

@ -131,12 +131,11 @@ function process.internal.close(thread, result)
checkArg(1,thread,"thread") checkArg(1,thread,"thread")
local pdata = process.info(thread).data local pdata = process.info(thread).data
pdata.result = result pdata.result = result
local handles = {} while pdata.handles[1] do
for s,_ in pairs(pdata.handles) do local h = table.remove(pdata.handles)
table.insert(handles, s) if h.close then
pcall(h.close, h)
end end
for _,v in ipairs(handles) do
pcall(v.close, v)
end end
process.list[thread] = nil process.list[thread] = nil
end end
@ -156,18 +155,28 @@ function process.internal.continue(co, ...)
return table.unpack(result, 2, result.n) return table.unpack(result, 2, result.n)
end end
function process.closeOnExit(stream, proc) function process.removeHandle(handle, proc)
local handles = (proc or process.info()).data.handles local handles = (proc or process.info()).data.handles
if not handles[stream] then for pos, h in ipairs(handles) do
handles[stream] = stream.close if h == handle then
stream.close = function(...) return table.remove(handles, pos)
local close = handles[stream]
handles[stream] = nil
if close then
return close(...)
end end
end end
end end
function process.addHandle(handle, proc)
local _close = handle.close
local handles = (proc or process.info()).data.handles
table.insert(handles, handle)
function handle:close(...)
if _close then
self.close = _close
_close = nil
process.removeHandle(self, proc)
return self:close(...)
end
end
return handle
end end
function process.running(level) -- kept for backwards compat, prefer process.info function process.running(level) -- kept for backwards compat, prefer process.info

View File

@ -114,7 +114,7 @@ function box_thread:attach(parent)
if mt.attached then if mt.attached then
-- registration happens on the attached proc, unregister before reparenting -- registration happens on the attached proc, unregister before reparenting
waiting_handler = mt.unregister() waiting_handler = mt.unregister()
mt.attached.data.handles[self] = nil process.removeHandle(self, mt.attached)
end end
-- fix close -- fix close
@ -122,7 +122,7 @@ function box_thread:attach(parent)
-- attach to parent or the current process -- attach to parent or the current process
mt.attached = proc mt.attached = proc
process.closeOnExit(self, proc) process.addHandle(self, proc)
-- register on the new parent -- register on the new parent
if waiting_handler then -- event-waiting if waiting_handler then -- event-waiting
@ -137,7 +137,7 @@ function thread.current()
local thread_root local thread_root
while proc do while proc do
if thread_root then if thread_root then
for handle in pairs(proc.data.handles) do for _,handle in ipairs(proc.data.handles) do
if handle.pco and handle.pco.root == thread_root then if handle.pco and handle.pco.root == thread_root then
return handle return handle
end end
@ -264,7 +264,7 @@ function thread.create(fp, ...)
function mt.close() function mt.close()
local old_status = t:status() local old_status = t:status()
mt.__status = "dead" mt.__status = "dead"
mt.attached.data.handles[t] = nil process.removeHandle(t, mt.attached)
if old_status ~= "dead" then if old_status ~= "dead" then
event.push("thread_exit") event.push("thread_exit")
end end