diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2024-05-27 12:19:20 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2024-05-27 20:56:49 -0700 |
| commit | 2367a1ff846ef2f146d4f7e449044970d399046b (patch) | |
| tree | c3dc18c77fc1b7c09f894b8c1d748b487eea18f7 /lib/std | |
| parent | dcf9cae2568a7422ab7885404da63fafa31b00fc (diff) | |
| download | zig-2367a1ff846ef2f146d4f7e449044970d399046b.tar.gz zig-2367a1ff846ef2f146d4f7e449044970d399046b.zip | |
std.Progress: handle short writes
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/Progress.zig | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/lib/std/Progress.zig b/lib/std/Progress.zig index bfdf0f7436..7653324187 100644 --- a/lib/std/Progress.zig +++ b/lib/std/Progress.zig @@ -993,6 +993,8 @@ fn write(buf: []const u8) anyerror!void { global_progress.written_newline_count = global_progress.accumulated_newline_count; } +var remaining_write_trash_bytes: usize = 0; + fn writeIpc(fd: posix.fd_t, serialized: Serialized) error{BrokenPipe}!void { // Byteswap if necessary to ensure little endian over the pipe. This is // needed because the parent or child process might be running in qemu. @@ -1004,18 +1006,35 @@ fn writeIpc(fd: posix.fd_t, serialized: Serialized) error{BrokenPipe}!void { const storage = std.mem.sliceAsBytes(serialized.storage); const parents = std.mem.sliceAsBytes(serialized.parents); - var vecs: [3]std.posix.iovec_const = .{ + var vecs: [3]posix.iovec_const = .{ .{ .base = header.ptr, .len = header.len }, .{ .base = storage.ptr, .len = storage.len }, .{ .base = parents.ptr, .len = parents.len }, }; + while (remaining_write_trash_bytes > 0) { + // We do this in a separate write call to give a better chance for the + // writev below to be in a single packet. + const n = @min(parents.len, remaining_write_trash_bytes); + if (posix.write(fd, parents[0..n])) |written| { + remaining_write_trash_bytes -= written; + continue; + } else |err| switch (err) { + error.WouldBlock => return, + error.BrokenPipe => return error.BrokenPipe, + else => |e| { + std.log.debug("failed to send progress to parent process: {s}", .{@errorName(e)}); + return error.BrokenPipe; + }, + } + } + // If this write would block we do not want to keep trying, but we need to // know if a partial message was written. if (posix.writev(fd, &vecs)) |written| { const total = header.len + storage.len + parents.len; if (written < total) { - std.log.debug("short write: {d} out of {d}", .{ written, total }); + remaining_write_trash_bytes = total - written; } } else |err| switch (err) { error.WouldBlock => {}, |
