Download:
child 38:a0523ef47e09
parent 36:e364e0f5ad89
37:e7e650632cc8
Anton Shestakov <av6@dwimlabs.net>, Sun, 23 Oct 2016 17:53:32 +0800
hglib: make inner loop in runcommand() use a coroutine Then it's possible to do something nontrivial using the more low-level client.runcommand_co().

1 файлов изменено, 27 вставок(+), 5 удалений(-) [+]
hglib.lua file | annotate | diff | comparison | revisions
--- a/hglib.lua Mon Oct 17 23:27:50 2016 +0800
+++ b/hglib.lua Sun Oct 23 17:53:32 2016 +0800
@@ -128,13 +128,32 @@
end
end
-function Client:runcommand(command, input)
+function Client:runcommand_co(command)
if not self.capabilities.runcommand then
- return nil, '', 'runcommand is not supported by this command server', ''
+ return nil, 'runcommand is not supported by this command server'
end
self.wh:write('runcommand\n')
write_block(self.wh, unpack(command))
self.wh:flush()
+ return coroutine.create(function()
+ while true do
+ local channel, message = read_channel(self.rh)
+ if channel == 'r' then
+ return channel, decode_i4(message)
+ elseif channel:lower() ~= channel and channel ~= 'I' and channel ~= 'L' then
+ return channel, message
+ else
+ coroutine.yield(channel, message)
+ end
+ end
+ end)
+end
+
+function Client:runcommand(command, input)
+ local co, err = self:runcommand_co(command)
+ if type(co) ~= 'thread' then
+ return nil, '', err, ''
+ end
local o = ''
local e = ''
local d = ''
@@ -143,10 +162,13 @@
self.wh:flush()
input = input:sub(length + 1)
end
- while true do
- local channel, message = read_channel(self.rh)
+ while coroutine.status(co) ~= 'dead' do
+ local status, channel, message = coroutine.resume(co)
+ if not status then
+ return nil, '', '\nhglib: coroutine failure: ' .. channel, ''
+ end
if channel == 'r' then
- return decode_i4(message), o, e, d
+ return message, o, e, d
elseif channel == 'o' then
o = o .. message
elseif channel == 'e' then