@@ -13,6 +13,7 @@ return function(spec)
13
13
local env , cwd = spec .env , spec .cwd
14
14
15
15
local finish_future = nio .control .future ()
16
+ local output_finish_future = nio .control .future ()
16
17
local result_code = nil
17
18
local command = spec .command
18
19
local output_accum = FanoutAccum (function (prev , new )
@@ -40,6 +41,10 @@ return function(spec)
40
41
height = spec .strategy .height ,
41
42
width = spec .strategy .width ,
42
43
on_stdout = function (_ , data )
44
+ if # data == 1 and data [1 ] == " " then
45
+ output_finish_future .set ()
46
+ return
47
+ end
43
48
output_accum :push (table.concat (data , " \n " ))
44
49
end ,
45
50
on_exit = function (_ , code )
@@ -69,7 +74,7 @@ return function(spec)
69
74
queue .put_nowait (d )
70
75
end )
71
76
return function ()
72
- local data = nio .first ({ queue .get , finish_future .wait })
77
+ local data = nio .first ({ queue .get , output_finish_future .wait })
73
78
if data then
74
79
return data
75
80
end
@@ -114,7 +119,17 @@ return function(spec)
114
119
end ,
115
120
result = function ()
116
121
if result_code == nil then
117
- finish_future :wait ()
122
+ finish_future .wait ()
123
+ if not output_finish_future .is_set () then
124
+ -- jobstart doesn't necessarily call on_stdout if the process
125
+ -- stops quickly, so add a timeout to prevent deadlock
126
+ nio .first ({
127
+ output_finish_future .wait ,
128
+ function ()
129
+ nio .sleep (100 )
130
+ end ,
131
+ })
132
+ end
118
133
end
119
134
local close_err = nio .uv .fs_close (output_fd )
120
135
assert (not close_err , close_err )
0 commit comments