mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-04-27 19:09:47 +03:00
std.Progress: implement ipc resource cleanup
This commit is contained in:
+20
-32
@@ -386,10 +386,14 @@ pub const ZigProcess = struct {
|
||||
child: std.process.Child,
|
||||
multi_reader_buffer: Io.File.MultiReader.Buffer(2),
|
||||
multi_reader: Io.File.MultiReader,
|
||||
progress_ipc_fd: if (std.Progress.have_ipc) ?std.posix.fd_t else void,
|
||||
progress_ipc_index: ?if (std.Progress.have_ipc) std.Progress.Ipc.Index else noreturn,
|
||||
|
||||
pub const StreamEnum = enum { stdout, stderr };
|
||||
|
||||
pub fn saveState(zp: *ZigProcess, prog_node: std.Progress.Node) void {
|
||||
zp.progress_ipc_index = if (std.Progress.have_ipc) prog_node.takeIpcIndex() else null;
|
||||
}
|
||||
|
||||
pub fn deinit(zp: *ZigProcess, io: Io) void {
|
||||
zp.child.kill(io);
|
||||
zp.multi_reader.deinit();
|
||||
@@ -417,7 +421,14 @@ pub fn evalZigProcess(
|
||||
|
||||
if (s.getZigProcess()) |zp| update: {
|
||||
assert(watch);
|
||||
if (std.Progress.have_ipc) if (zp.progress_ipc_fd) |fd| prog_node.setIpcFd(fd);
|
||||
if (zp.progress_ipc_index) |ipc_index| prog_node.setIpcIndex(ipc_index);
|
||||
zp.progress_ipc_index = null;
|
||||
var exited = false;
|
||||
defer if (exited) {
|
||||
s.cast(Compile).?.zig_process = null;
|
||||
zp.deinit(io);
|
||||
gpa.destroy(zp);
|
||||
} else zp.saveState(prog_node);
|
||||
const result = zigProcessUpdate(s, zp, watch, web_server, gpa) catch |err| switch (err) {
|
||||
error.BrokenPipe, error.EndOfStream => |reason| {
|
||||
std.log.info("{s} restart required: {t}", .{ argv[0], reason });
|
||||
@@ -426,7 +437,7 @@ pub fn evalZigProcess(
|
||||
return s.fail("unable to wait for {s}: {t}", .{ argv[0], e });
|
||||
};
|
||||
_ = term;
|
||||
s.clearZigProcess(gpa);
|
||||
exited = true;
|
||||
break :update;
|
||||
},
|
||||
else => |e| return e,
|
||||
@@ -442,7 +453,7 @@ pub fn evalZigProcess(
|
||||
return s.fail("unable to wait for {s}: {t}", .{ argv[0], e });
|
||||
};
|
||||
s.result_peak_rss = zp.child.resource_usage_statistics.getMaxRss() orelse 0;
|
||||
s.clearZigProcess(gpa);
|
||||
exited = true;
|
||||
try handleChildProcessTerm(s, term);
|
||||
return error.MakeFailed;
|
||||
}
|
||||
@@ -467,19 +478,16 @@ pub fn evalZigProcess(
|
||||
.progress_node = prog_node,
|
||||
}) catch |err| return s.fail("failed to spawn zig compiler {s}: {t}", .{ argv[0], err });
|
||||
|
||||
zp.* = .{
|
||||
.child = zp.child,
|
||||
.multi_reader_buffer = undefined,
|
||||
.multi_reader = undefined,
|
||||
.progress_ipc_fd = if (std.Progress.have_ipc) prog_node.getIpcFd() else {},
|
||||
};
|
||||
zp.multi_reader.init(gpa, io, zp.multi_reader_buffer.toStreams(), &.{
|
||||
zp.child.stdout.?, zp.child.stderr.?,
|
||||
});
|
||||
if (watch) s.setZigProcess(zp);
|
||||
if (watch) s.cast(Compile).?.zig_process = zp;
|
||||
defer if (!watch) zp.deinit(io);
|
||||
|
||||
const result = try zigProcessUpdate(s, zp, watch, web_server, gpa);
|
||||
const result = result: {
|
||||
defer if (watch) zp.saveState(prog_node);
|
||||
break :result try zigProcessUpdate(s, zp, watch, web_server, gpa);
|
||||
};
|
||||
|
||||
if (!watch) {
|
||||
// Send EOF to stdin.
|
||||
@@ -670,26 +678,6 @@ pub fn getZigProcess(s: *Step) ?*ZigProcess {
|
||||
};
|
||||
}
|
||||
|
||||
fn setZigProcess(s: *Step, zp: *ZigProcess) void {
|
||||
switch (s.id) {
|
||||
.compile => s.cast(Compile).?.zig_process = zp,
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
fn clearZigProcess(s: *Step, gpa: Allocator) void {
|
||||
switch (s.id) {
|
||||
.compile => {
|
||||
const compile = s.cast(Compile).?;
|
||||
if (compile.zig_process) |zp| {
|
||||
gpa.destroy(zp);
|
||||
compile.zig_process = null;
|
||||
}
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
fn sendMessage(io: Io, file: Io.File, tag: std.zig.Client.Message.Tag) !void {
|
||||
const header: std.zig.Client.Message.Header = .{
|
||||
.tag = tag,
|
||||
|
||||
Reference in New Issue
Block a user