aboutsummaryrefslogtreecommitdiff
path: root/lib/std/Io/Threaded.zig
diff options
context:
space:
mode:
Diffstat (limited to 'lib/std/Io/Threaded.zig')
-rw-r--r--lib/std/Io/Threaded.zig83
1 files changed, 53 insertions, 30 deletions
diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig
index f375bbcb7c..3e7b6950d4 100644
--- a/lib/std/Io/Threaded.zig
+++ b/lib/std/Io/Threaded.zig
@@ -82,8 +82,8 @@ stderr_writer: File.Writer = .{
.io = undefined,
.interface = Io.File.Writer.initInterface(&.{}),
.file = if (is_windows) undefined else .stderr(),
- .mode = undefined,
},
+stderr_mode: Io.Terminal.Mode = .no_color,
stderr_writer_initialized: bool = false,
pub const RobustCancel = if (std.Thread.use_pthreads or native_os == .linux) enum {
@@ -755,9 +755,9 @@ pub fn io(t: *Threaded) Io {
.processExecutableOpen = processExecutableOpen,
.processExecutablePath = processExecutablePath,
- .lockStderrWriter = lockStderrWriter,
- .tryLockStderrWriter = tryLockStderrWriter,
- .unlockStderrWriter = unlockStderrWriter,
+ .lockStderr = lockStderr,
+ .tryLockStderr = tryLockStderr,
+ .unlockStderr = unlockStderr,
.now = now,
.sleep = sleep,
@@ -887,9 +887,9 @@ pub fn ioBasic(t: *Threaded) Io {
.processExecutableOpen = processExecutableOpen,
.processExecutablePath = processExecutablePath,
- .lockStderrWriter = lockStderrWriter,
- .tryLockStderrWriter = tryLockStderrWriter,
- .unlockStderrWriter = unlockStderrWriter,
+ .lockStderr = lockStderr,
+ .tryLockStderr = tryLockStderr,
+ .unlockStderr = unlockStderr,
.now = now,
.sleep = sleep,
@@ -10090,47 +10090,70 @@ fn netLookupFallible(
return error.OptionUnsupported;
}
-fn lockStderrWriter(userdata: ?*anyopaque, buffer: []u8) Io.Cancelable!*File.Writer {
+fn lockStderr(
+ userdata: ?*anyopaque,
+ buffer: []u8,
+ terminal_mode: ?Io.Terminal.Mode,
+) Io.Cancelable!Io.LockedStderr {
const t: *Threaded = @ptrCast(@alignCast(userdata));
// Only global mutex since this is Threaded.
- Io.stderr_thread_mutex.lock();
- if (!t.stderr_writer_initialized) {
- const io_t = ioBasic(t);
- if (is_windows) t.stderr_writer.file = .stderr();
- t.stderr_writer.io = io_t;
- t.stderr_writer.mode = try .detect(io_t, t.stderr_writer.file, true, .streaming_simple);
- t.stderr_writer_initialized = true;
- }
- std.Progress.clearWrittenWithEscapeCodes(&t.stderr_writer) catch {};
- t.stderr_writer.interface.flush() catch {};
- t.stderr_writer.interface.buffer = buffer;
- return &t.stderr_writer;
+ std.process.stderr_thread_mutex.lock();
+ return initLockedStderr(t, buffer, terminal_mode);
}
-fn tryLockStderrWriter(userdata: ?*anyopaque, buffer: []u8) ?*File.Writer {
+fn tryLockStderr(
+ userdata: ?*anyopaque,
+ buffer: []u8,
+ terminal_mode: ?Io.Terminal.Mode,
+) Io.Cancelable!?Io.LockedStderr {
const t: *Threaded = @ptrCast(@alignCast(userdata));
// Only global mutex since this is Threaded.
- if (!Io.stderr_thread_mutex.tryLock()) return null;
+ if (!std.process.stderr_thread_mutex.tryLock()) return null;
+ return try initLockedStderr(t, buffer, terminal_mode);
+}
+
+fn initLockedStderr(
+ t: *Threaded,
+ buffer: []u8,
+ terminal_mode: ?Io.Terminal.Mode,
+) Io.Cancelable!Io.LockedStderr {
if (!t.stderr_writer_initialized) {
const io_t = ioBasic(t);
if (is_windows) t.stderr_writer.file = .stderr();
t.stderr_writer.io = io_t;
- t.stderr_writer.mode = File.Writer.Mode.detect(io_t, t.stderr_writer.file, true, .streaming_simple) catch
- return null;
t.stderr_writer_initialized = true;
+ t.stderr_mode = terminal_mode orelse try .detect(io_t, t.stderr_writer.file);
}
- std.Progress.clearWrittenWithEscapeCodes(&t.stderr_writer) catch {};
- t.stderr_writer.interface.flush() catch {};
+ std.Progress.clearWrittenWithEscapeCodes(&t.stderr_writer) catch |err| switch (err) {
+ error.WriteFailed => switch (t.stderr_writer.err.?) {
+ error.Canceled => |e| return e,
+ else => {},
+ },
+ };
+ t.stderr_writer.interface.flush() catch |err| switch (err) {
+ error.WriteFailed => switch (t.stderr_writer.err.?) {
+ error.Canceled => |e| return e,
+ else => {},
+ },
+ };
t.stderr_writer.interface.buffer = buffer;
- return &t.stderr_writer;
+ return .{
+ .file_writer = &t.stderr_writer,
+ .terminal_mode = t.stderr_mode,
+ };
}
-fn unlockStderrWriter(userdata: ?*anyopaque) void {
+fn unlockStderr(userdata: ?*anyopaque) void {
const t: *Threaded = @ptrCast(@alignCast(userdata));
- t.stderr_writer.interface.flush() catch {};
+ t.stderr_writer.interface.flush() catch |err| switch (err) {
+ error.WriteFailed => switch (t.stderr_writer.err.?) {
+ error.Canceled => @panic("TODO make this uncancelable"),
+ else => {},
+ },
+ };
t.stderr_writer.interface.end = 0;
t.stderr_writer.interface.buffer = &.{};
- Io.stderr_thread_mutex.unlock();
+ std.process.stderr_thread_mutex.unlock();
}
pub const PosixAddress = extern union {