Skip to content

Commit b60e9f2

Browse files
authored
Merge pull request #24394 from ziglang/fixes
buffering fixes
2 parents eb37552 + e255415 commit b60e9f2

File tree

4 files changed

+29
-14
lines changed

4 files changed

+29
-14
lines changed

lib/std/Io/Reader.zig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,9 @@ pub fn peekDelimiterExclusive(r: *Reader, delimiter: u8) DelimiterError![]u8 {
840840
/// Returns number of bytes streamed, which may be zero, or error.EndOfStream
841841
/// if the delimiter was not found.
842842
///
843+
/// Asserts buffer capacity of at least one. This function performs better with
844+
/// larger buffers.
845+
///
843846
/// See also:
844847
/// * `streamDelimiterEnding`
845848
/// * `streamDelimiterLimit`
@@ -858,6 +861,9 @@ pub fn streamDelimiter(r: *Reader, w: *Writer, delimiter: u8) StreamError!usize
858861
/// Returns number of bytes streamed, which may be zero. End of stream can be
859862
/// detected by checking if the next byte in the stream is the delimiter.
860863
///
864+
/// Asserts buffer capacity of at least one. This function performs better with
865+
/// larger buffers.
866+
///
861867
/// See also:
862868
/// * `streamDelimiter`
863869
/// * `streamDelimiterLimit`
@@ -884,6 +890,9 @@ pub const StreamDelimiterLimitError = error{
884890
///
885891
/// Returns number of bytes streamed, which may be zero. End of stream can be
886892
/// detected by checking if the next byte in the stream is the delimiter.
893+
///
894+
/// Asserts buffer capacity of at least one. This function performs better with
895+
/// larger buffers.
887896
pub fn streamDelimiterLimit(
888897
r: *Reader,
889898
w: *Writer,

lib/std/Io/Writer.zig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,10 @@ pub fn writeAllPreserve(w: *Writer, preserve_length: usize, bytes: []const u8) E
572572
/// A user type may be a `struct`, `vector`, `union` or `enum` type.
573573
///
574574
/// To print literal curly braces, escape them by writing them twice, e.g. `{{` or `}}`.
575+
///
576+
/// Asserts `buffer` capacity of at least 2 if a union is printed. This
577+
/// requirement could be lifted by adjusting the code, but if you trigger that
578+
/// assertion it is a clue that you should probably be using a buffer.
575579
pub fn print(w: *Writer, comptime fmt: []const u8, args: anytype) Error!void {
576580
const ArgsType = @TypeOf(args);
577581
const args_type_info = @typeInfo(ArgsType);
@@ -942,6 +946,7 @@ pub fn printAddress(w: *Writer, value: anytype) Error!void {
942946
@compileError("cannot format non-pointer type " ++ @typeName(T) ++ " with * specifier");
943947
}
944948

949+
/// Asserts `buffer` capacity of at least 2 if `value` is a union.
945950
pub fn printValue(
946951
w: *Writer,
947952
comptime fmt: []const u8,

lib/std/debug.zig

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,14 @@ pub fn unlockStderrWriter() void {
219219
std.Progress.unlockStderrWriter();
220220
}
221221

222-
/// Print to stderr, unbuffered, and silently returning on failure. Intended
223-
/// for use in "printf debugging". Use `std.log` functions for proper logging.
222+
/// Print to stderr, silently returning on failure. Intended for use in "printf
223+
/// debugging". Use `std.log` functions for proper logging.
224+
///
225+
/// Uses a 64-byte buffer for formatted printing which is flushed before this
226+
/// function returns.
224227
pub fn print(comptime fmt: []const u8, args: anytype) void {
225-
const bw = lockStderrWriter(&.{});
228+
var buffer: [64]u8 = undefined;
229+
const bw = lockStderrWriter(&buffer);
226230
defer unlockStderrWriter();
227231
nosuspend bw.print(fmt, args) catch return;
228232
}

lib/std/log.zig

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,11 @@ pub fn defaultLogEnabled(comptime message_level: Level) bool {
137137
return comptime logEnabled(message_level, default_log_scope);
138138
}
139139

140-
/// The default implementation for the log function, custom log functions may
140+
/// The default implementation for the log function. Custom log functions may
141141
/// forward log messages to this function.
142+
///
143+
/// Uses a 64-byte buffer for formatted printing which is flushed before this
144+
/// function returns.
142145
pub fn defaultLog(
143146
comptime message_level: Level,
144147
comptime scope: @Type(.enum_literal),
@@ -147,16 +150,10 @@ pub fn defaultLog(
147150
) void {
148151
const level_txt = comptime message_level.asText();
149152
const prefix2 = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): ";
150-
const stderr = std.fs.File.stderr().deprecatedWriter();
151-
var bw = std.io.bufferedWriter(stderr);
152-
const writer = bw.writer();
153-
154-
std.debug.lockStdErr();
155-
defer std.debug.unlockStdErr();
156-
nosuspend {
157-
writer.print(level_txt ++ prefix2 ++ format ++ "\n", args) catch return;
158-
bw.flush() catch return;
159-
}
153+
var buffer: [64]u8 = undefined;
154+
const stderr = std.debug.lockStderrWriter(&buffer);
155+
defer std.debug.unlockStderrWriter();
156+
nosuspend stderr.print(level_txt ++ prefix2 ++ format ++ "\n", args) catch return;
160157
}
161158

162159
/// Returns a scoped logging namespace that logs all messages using the scope

0 commit comments

Comments
 (0)