Skip to content

Commit 0699dc5

Browse files
mrjbq7Cloudef
authored andcommitted
update for writergate
1 parent 57650f9 commit 0699dc5

File tree

13 files changed

+105
-83
lines changed

13 files changed

+105
-83
lines changed

bugs/31.zig

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,15 @@ fn protection(comptime func: anytype, args: anytype) void {
2323
}
2424

2525
pub fn logInfo(comptime format: []const u8, args: anytype) void {
26-
std.io.getStdOut().writer().print(format, args) catch return;
26+
var buf: [4096]u8 = undefined;
27+
var writer = std.fs.File.stdout().writerStreaming(&buf);
28+
writer.interface.print(format, args) catch return;
2729
}
2830

2931
pub fn logErr(comptime format: []const u8, args: anytype) void {
30-
std.io.getStdErr().writer().print(format, args) catch return;
32+
var buf: [4096]u8 = undefined;
33+
var writer = std.fs.File.stderr().writerStreaming(&buf);
34+
writer.interface.print(format, args) catch return;
3135
}
3236

3337
pub fn delay(ns: u128) !void {

build.zig

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,18 @@ pub fn build(b: *std.Build) void {
7070
.coro_wttr,
7171
}) |example| {
7272
const os = target.query.os_tag orelse builtin.os.tag;
73-
const exe = b.addExecutable(.{
74-
.name = @tagName(example),
73+
const module = b.createModule(.{
7574
.root_source_file = b.path("examples/" ++ @tagName(example) ++ ".zig"),
7675
.target = target,
7776
.optimize = optimize,
7877
.sanitize_thread = sanitize,
7978
.single_threaded = if (example == .coro_wttr and os != .wasi) false else single_threaded,
8079
.strip = false,
8180
});
81+
const exe = b.addExecutable(.{
82+
.name = @tagName(example),
83+
.root_module = module,
84+
});
8285
exe.root_module.addImport("aio", aio);
8386
exe.root_module.addImport("coro", coro);
8487
const install = b.addInstallArtifact(exe, .{ .dest_dir = .{ .override = .{ .custom = "example" } } });
@@ -90,16 +93,19 @@ pub fn build(b: *std.Build) void {
9093
const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match any filter") orelse "";
9194
const test_step = b.step("test", "Run unit tests");
9295
inline for (.{ .minilib, .aio, .coro }) |mod| {
93-
const tst = b.addTest(.{
96+
const module = b.createModule(.{
9497
.root_source_file = b.path("src/" ++ @tagName(mod) ++ ".zig"),
9598
.target = target,
9699
.optimize = optimize,
97-
.filters = &.{test_filter},
98100
.link_libc = aio.link_libc,
99101
.sanitize_thread = sanitize,
100102
.single_threaded = single_threaded,
101103
.strip = false,
102104
});
105+
const tst = b.addTest(.{
106+
.root_module = module,
107+
.filters = &.{test_filter},
108+
});
103109
switch (mod) {
104110
.minilib => addImportsFrom(tst.root_module, minilib),
105111
.aio => addImportsFrom(tst.root_module, aio),
@@ -119,8 +125,7 @@ pub fn build(b: *std.Build) void {
119125
.ticker,
120126
.backend_override,
121127
}) |bug| {
122-
const exe = b.addExecutable(.{
123-
.name = @tagName(bug),
128+
const module = b.createModule(.{
124129
.root_source_file = b.path("bugs/" ++ @tagName(bug) ++ ".zig"),
125130
.target = target,
126131
.optimize = switch (bug) {
@@ -132,6 +137,10 @@ pub fn build(b: *std.Build) void {
132137
.single_threaded = single_threaded,
133138
.strip = false,
134139
});
140+
const exe = b.addExecutable(.{
141+
.name = @tagName(bug),
142+
.root_module = module,
143+
});
135144
exe.root_module.addImport("aio", aio);
136145
exe.root_module.addImport("coro", coro);
137146
var cmd = makeRunStep(b, target, exe, "bug:" ++ @tagName(bug), "Check regression for #" ++ @tagName(bug), .{});
@@ -150,15 +159,18 @@ pub fn build(b: *std.Build) void {
150159
.spawn_managed,
151160
.spawn_unmanaged,
152161
}) |bench| {
153-
const exe = b.addExecutable(.{
154-
.name = @tagName(bench),
162+
const module = b.createModule(.{
155163
.root_source_file = b.path("bench/" ++ @tagName(bench) ++ ".zig"),
156164
.target = target,
157165
.optimize = .ReleaseFast,
158166
.sanitize_thread = sanitize,
159167
.single_threaded = single_threaded,
160168
.strip = false,
161169
});
170+
const exe = b.addExecutable(.{
171+
.name = @tagName(bench),
172+
.root_module = module,
173+
});
162174
exe.root_module.addImport("aio", aio);
163175
exe.root_module.addImport("coro", coro);
164176
const install = b.addInstallArtifact(exe, .{ .dest_dir = .{ .override = .{ .custom = "bench" } } });

build.zig.zon

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
.fingerprint = 0xdf66d422DEADBEEF,
55
.dependencies = .{
66
.zigwin32 = .{
7-
.url = "git+https://github.com/marlersoft/zigwin32.git#0d804dce7632d0912245b1a7aa0384a21629f453",
8-
.hash = "zigwin32-25.0.28-preview-AAAAAC8f_AP71CpFWpTOITTECAoWyZB0-yjKlN-H3ePP",
7+
.url = "git+https://github.com/marlersoft/zigwin32.git#9d399c0895de4746c1fcab366841e2ab031b0429",
8+
.hash = "zigwin32-25.0.28-preview-AAAAANd_5APbcon3QqoYfLKnJ13fiBGJSGq9YrVZsfI-",
99
.lazy = true,
1010
},
1111
},

examples/coro_wttr.zig

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,37 +10,37 @@ pub const std_options: std.Options = .{
1010

1111
fn getWeather(completed: *std.atomic.Value(u32), allocator: std.mem.Allocator, city: []const u8, lang: []const u8) anyerror![]const u8 {
1212
defer _ = completed.fetchAdd(1, .monotonic);
13-
var url: std.BoundedArray(u8, 256) = .{};
13+
var url_buf: [256]u8 = undefined;
14+
var url_writer: std.Io.Writer = .fixed(&url_buf);
1415
if (builtin.target.os.tag == .windows) {
15-
try url.writer().print("https://wttr.in/{s}?AFT&lang={s}", .{ city, lang });
16+
try url_writer.print("https://wttr.in/{s}?AFT&lang={s}", .{ city, lang });
1617
} else {
17-
try url.writer().print("https://wttr.in/{s}?AF&lang={s}", .{ city, lang });
18+
try url_writer.print("https://wttr.in/{s}?AF&lang={s}", .{ city, lang });
1819
}
19-
var body = std.ArrayList(u8).init(allocator);
20-
errdefer body.deinit();
20+
var body_writer: std.Io.Writer.Allocating = .init(allocator);
2121
var client: std.http.Client = .{ .allocator = allocator };
2222
defer client.deinit();
2323
_ = try client.fetch(.{
24-
.location = .{ .url = url.constSlice() },
25-
.response_storage = .{ .dynamic = &body },
24+
.location = .{ .url = url_writer.buffered() },
25+
.response_writer = &body_writer.writer,
2626
});
27-
return body.toOwnedSlice();
27+
return try body_writer.toOwnedSlice();
2828
}
2929

3030
fn getLatestZig(completed: *std.atomic.Value(u32), allocator: std.mem.Allocator) anyerror![]const u8 {
3131
defer _ = completed.fetchAdd(1, .monotonic);
32-
var body = std.ArrayList(u8).init(allocator);
33-
defer body.deinit();
32+
var body_writer: std.Io.Writer.Allocating = .init(allocator);
33+
defer body_writer.deinit();
3434
var client: std.http.Client = .{ .allocator = allocator };
3535
defer client.deinit();
3636
_ = try client.fetch(.{
3737
.location = .{ .url = "https://ziglang.org/download/index.json" },
38-
.response_storage = .{ .dynamic = &body },
38+
.response_writer = &body_writer.writer,
3939
});
4040
const Index = struct {
4141
master: struct { version: []const u8 },
4242
};
43-
var parsed = try std.json.parseFromSlice(Index, allocator, body.items, .{ .ignore_unknown_fields = true });
43+
var parsed = try std.json.parseFromSlice(Index, allocator, body_writer.written(), .{ .ignore_unknown_fields = true });
4444
defer parsed.deinit();
4545
return allocator.dupe(u8, parsed.value.master.version);
4646
}
@@ -86,13 +86,13 @@ pub fn main() !void {
8686
var tpool: coro.ThreadPool = try coro.ThreadPool.init(gpa.allocator(), .{});
8787
defer tpool.deinit();
8888

89-
var tasks = std.ArrayList(coro.Task.Generic(anyerror![]const u8)).init(allocator);
90-
defer tasks.deinit();
89+
var tasks: std.ArrayList(coro.Task.Generic(anyerror![]const u8)) = .empty;
90+
defer tasks.deinit(allocator);
9191

92-
try tasks.append(try tpool.spawnForCompletion(&scheduler, getWeather, .{ &completed, allocator, "oulu", "fi" }));
93-
try tasks.append(try tpool.spawnForCompletion(&scheduler, getWeather, .{ &completed, allocator, "tokyo", "ja" }));
94-
try tasks.append(try tpool.spawnForCompletion(&scheduler, getWeather, .{ &completed, allocator, "portland", "en" }));
95-
try tasks.append(try tpool.spawnForCompletion(&scheduler, getLatestZig, .{ &completed, allocator }));
92+
try tasks.append(allocator, try tpool.spawnForCompletion(&scheduler, getWeather, .{ &completed, allocator, "oulu", "fi" }));
93+
try tasks.append(allocator, try tpool.spawnForCompletion(&scheduler, getWeather, .{ &completed, allocator, "tokyo", "ja" }));
94+
try tasks.append(allocator, try tpool.spawnForCompletion(&scheduler, getWeather, .{ &completed, allocator, "portland", "en" }));
95+
try tasks.append(allocator, try tpool.spawnForCompletion(&scheduler, getLatestZig, .{ &completed, allocator }));
9696

9797
max = @intCast(tasks.items.len);
9898
while (completed.load(.acquire) < tasks.items.len) {
@@ -102,18 +102,23 @@ pub fn main() !void {
102102
// don't really have to call this, but I want the defer that cleans the progress bar to run
103103
ltask.cancel();
104104

105+
var stdout_buf: [4096]u8 = undefined;
106+
var stdout_writer = std.fs.File.stdout().writer(&stdout_buf);
107+
var stdout = &stdout_writer.interface;
108+
defer stdout.flush() catch {};
109+
105110
for (tasks.items, 0..) |task, idx| {
106111
if (task.complete(.wait)) |body| {
107112
defer allocator.free(body);
108113
if (idx == 3) {
109-
try std.io.getStdOut().writer().print("\nAaand the current master zig version is... ", .{});
114+
try stdout.print("\nAaand the current master zig version is... ", .{});
110115
}
111-
try std.io.getStdOut().writeAll(body);
112-
try std.io.getStdOut().writeAll("\n");
116+
try stdout.writeAll(body);
117+
try stdout.writeAll("\n");
113118
} else |err| {
114-
try std.io.getStdOut().writer().print("request {} failed with: {}\n", .{ idx, err });
119+
try stdout.print("request {} failed with: {}\n", .{ idx, err });
115120
}
116121
}
117122

118-
try std.io.getStdOut().writer().print("\nThat's all folks\n", .{});
123+
try stdout.print("\nThat's all folks\n", .{});
119124
}

src/aio.zig

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -278,13 +278,13 @@ test "shared outputs" {
278278
try std.testing.expect(id1 != id2);
279279
try std.testing.expect(id1 != id3);
280280
try std.testing.expect(id2 != id3);
281-
std.debug.print("{}\n", .{id1});
282-
std.debug.print("{}\n", .{id2});
283-
std.debug.print("{}\n", .{id3});
281+
std.debug.print("{f}\n", .{id1});
282+
std.debug.print("{f}\n", .{id2});
283+
std.debug.print("{f}\n", .{id3});
284284
_ = try dynamic.completeAll({});
285-
std.debug.print("{}\n", .{id1});
286-
std.debug.print("{}\n", .{id2});
287-
std.debug.print("{}\n", .{id3});
285+
std.debug.print("{f}\n", .{id1});
286+
std.debug.print("{f}\n", .{id2});
287+
std.debug.print("{f}\n", .{id3});
288288
}
289289

290290
test "Nop" {
@@ -644,7 +644,7 @@ test "ChildExit" {
644644
.linux, .freebsd, .openbsd, .dragonfly, .netbsd, .macos, .ios, .watchos, .visionos, .tvos => blk: {
645645
const pid = try std.posix.fork();
646646
if (pid == 0) {
647-
std.time.sleep(1 * std.time.ns_per_s);
647+
std.Thread.sleep(1 * std.time.ns_per_s);
648648
std.posix.exit(69);
649649
}
650650
break :blk pid;

src/aio/IoUring.zig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ pub fn queue(self: *@This(), pairs: anytype, handler: anytype) aio.Error!void {
161161
if (comptime pairs.len > 1) {
162162
var ids: std.BoundedArray(aio.Id, pairs.len) = .{};
163163
errdefer inline for (ids.constSlice(), pairs) |id, pair| {
164-
debug("dequeue: {}: {}, {s}", .{ id, pair.tag, @tagName(pair.link) });
164+
debug("dequeue: {f}: {any}, {s}", .{ id, pair.tag, @tagName(pair.link) });
165165
self.ops.release(id) catch unreachable;
166166
};
167167
inline for (pairs) |pair| ids.append(try self.queueOperation(pair.tag, pair.op, pair.link)) catch unreachable;
@@ -449,7 +449,7 @@ fn uring_init(n: u16) aio.Error!std.os.linux.IoUring {
449449
}
450450

451451
fn uring_queue(io: *std.os.linux.IoUring, comptime op_type: Operation, op: op_type.Type(), link: aio.Link, user_data: u64, state: *UringOperation.State) aio.Error!void {
452-
debug("queue: {}: {}", .{ aio.Id.init(user_data), op_type });
452+
debug("queue: {f}: {}", .{ aio.Id.init(user_data), op_type });
453453
const Trash = struct {
454454
var u_64: u64 align(1) = undefined;
455455
};
@@ -977,13 +977,13 @@ fn uring_handle_completion(comptime op_type: Operation, op: op_type.Type(), stat
977977
if (op_type == .link_timeout and res == error.Canceled) {
978978
// special case
979979
} else {
980-
debug("complete: {}: {} [FAIL] {}", .{ aio.Id.init(cqe.user_data), op_type, res });
980+
debug("complete: {f}: {} [FAIL] {}", .{ aio.Id.init(cqe.user_data), op_type, res });
981981
return error.OperationFailed;
982982
}
983983
}
984984
}
985985

986-
debug("complete: {}: {} [OK]", .{ aio.Id.init(cqe.user_data), op_type });
986+
debug("complete: {f}: {} [OK]", .{ aio.Id.init(cqe.user_data), op_type });
987987

988988
switch (op_type) {
989989
.nop => {},

src/aio/Posix.zig

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -184,27 +184,27 @@ pub fn complete(self: *@This(), mode: aio.CompletionMode, handler: anytype) aio.
184184
switch (op_type) {
185185
inline else => |tag| {
186186
if (hasField(tag.Type().Error, "BrokenPipe")) {
187-
Uringlator.debug("poll: {}: {} => ERR (BrokenPipe)", .{ id, op_type });
187+
Uringlator.debug("poll: {f}: {any} => ERR (BrokenPipe)", .{ id, op_type });
188188
self.uringlator.finish(self, id, error.BrokenPipe, .thread_unsafe);
189189
} else {
190-
Uringlator.debug("poll: {}: {} => ERR (Unexpected)", .{ id, op_type });
190+
Uringlator.debug("poll: {f}: {any} => ERR (Unexpected)", .{ id, op_type });
191191
self.uringlator.finish(self, id, error.Unexpected, .thread_unsafe);
192192
}
193193
continue :again;
194194
},
195195
}
196196
} else {
197-
Uringlator.debug("poll: {}: {} => NVAL (Unexpected)", .{ id, op_type });
197+
Uringlator.debug("poll: {f}: {any} => NVAL (Unexpected)", .{ id, op_type });
198198
self.uringlator.finish(self, id, error.Unexpected, .thread_unsafe);
199199
continue :again;
200200
}
201201
}
202202

203203
// start it for real this time
204204
if (self.uringlator.ops.getOne(.next, id) != id) {
205-
Uringlator.debug("ready: {}: {} => {}", .{ id, op_type, self.uringlator.ops.getOne(.next, id) });
205+
Uringlator.debug("ready: {f}: {any} => {f}", .{ id, op_type, self.uringlator.ops.getOne(.next, id) });
206206
} else {
207-
Uringlator.debug("ready: {}: {}", .{ id, op_type });
207+
Uringlator.debug("ready: {f}: {any}", .{ id, op_type });
208208
}
209209

210210
try self.uringlator_start(id, op_type);
@@ -500,9 +500,9 @@ pub fn uringlator_start(self: *@This(), id: aio.Id, op_type: Operation) !void {
500500

501501
// pending for readiness, perform the operation later
502502
if (self.uringlator.ops.getOne(.next, id) != id) {
503-
Uringlator.debug("pending: {}: {} => {}", .{ id, op_type, self.uringlator.ops.getOne(.next, id) });
503+
Uringlator.debug("pending: {f}: {any} => {f}", .{ id, op_type, self.uringlator.ops.getOne(.next, id) });
504504
} else {
505-
Uringlator.debug("pending: {}: {}", .{ id, op_type });
505+
Uringlator.debug("pending: {f}: {any}", .{ id, op_type });
506506
}
507507

508508
const readiness = self.uringlator.ops.getOne(.readiness, id);

src/aio/posix/wasi.zig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const std = @import("std");
22
const posix = @import("posix.zig");
3+
const BoundedArray = @import("minilib").BoundedArray;
34
const options = @import("../../aio.zig").options;
45
const log = std.log.scoped(.aio_wasi);
56

@@ -207,7 +208,7 @@ fn clock(userdata: usize, timeout: i32) std.os.wasi.subscription_t {
207208
pub fn poll(fds: []std.posix.pollfd, timeout: i32) std.posix.PollError!usize {
208209
// TODO: maybe use thread local arena instead?
209210
const MAX_POLL_FDS = 4096;
210-
var subs: std.BoundedArray(std.os.wasi.subscription_t, MAX_POLL_FDS) = .{};
211+
var subs: BoundedArray(std.os.wasi.subscription_t, MAX_POLL_FDS) = .{};
211212
for (fds) |*pfd| {
212213
pfd.revents = 0;
213214
if (pfd.events & std.posix.POLL.IN != 0) {

src/aio/uringlator.zig

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ pub fn Uringlator(BackendOperation: type) type {
244244

245245
fn queueOperation(self: *@This(), comptime tag: Operation, op: anytype, link: aio.Link, backend: anytype) aio.Error!aio.Id {
246246
const id = self.ops.next() orelse return error.OutOfMemory;
247-
debug("queue: {}: {}, {s} ({?})", .{ id, tag, @tagName(link), self.prev_id });
247+
debug("queue: {f}: {any}, {s} ({?f})", .{ id, tag, @tagName(link), self.prev_id });
248248

249249
const uop: UringlatorOperation = .{
250250
.type = tag,
@@ -285,7 +285,7 @@ pub fn Uringlator(BackendOperation: type) type {
285285
if (comptime pairs.len > 1) {
286286
var ids: std.BoundedArray(aio.Id, pairs.len) = .{};
287287
errdefer inline for (ids.constSlice(), pairs) |id, pair| {
288-
debug("dequeue: {}: {}, {s} ({?})", .{ id, pair.tag, @tagName(pair.link), self.prev_id });
288+
debug("dequeue: {f}: {any}, {s} ({?f})", .{ id, pair.tag, @tagName(pair.link), self.prev_id });
289289
backend.uringlator_dequeue(id, pair.tag, pair.op);
290290
self.ops.release(id) catch unreachable;
291291
};
@@ -347,9 +347,9 @@ pub fn Uringlator(BackendOperation: type) type {
347347

348348
fn start(self: *@This(), op_type: Operation, id: aio.Id, backend: anytype) aio.Error!void {
349349
if (self.ops.getOne(.next, id) != id) {
350-
debug("perform: {}: {} => {}", .{ id, op_type, self.ops.getOne(.next, id) });
350+
debug("perform: {f}: {any} => {f}", .{ id, op_type, self.ops.getOne(.next, id) });
351351
} else {
352-
debug("perform: {}: {}", .{ id, op_type });
352+
debug("perform: {f}: {any}", .{ id, op_type });
353353
}
354354
std.debug.assert(!self.started.isSet(id.slot));
355355
self.started.set(id.slot);
@@ -425,9 +425,9 @@ pub fn Uringlator(BackendOperation: type) type {
425425
};
426426

427427
if (failed) {
428-
debug("complete: {}: {} [FAIL] {}", .{ res.id, op_type, failure });
428+
debug("complete: {f}: {any} [FAIL] {any}", .{ res.id, op_type, failure });
429429
} else {
430-
debug("complete: {}: {} [OK]", .{ res.id, op_type });
430+
debug("complete: {f}: {any} [OK]", .{ res.id, op_type });
431431
}
432432

433433
num_errors += @intFromBool(failed);
@@ -497,7 +497,7 @@ pub fn Uringlator(BackendOperation: type) type {
497497
};
498498

499499
pub fn finish(self: *@This(), backend: anytype, id: aio.Id, failure: Operation.Error, comptime safety: Safety) void {
500-
debug("finish: {} {}", .{ id, failure });
500+
debug("finish: {f} {any}", .{ id, failure });
501501
if (safety == .thread_unsafe) self.ops.lookup(id) catch unreachable; // trying to finish nonexistant id
502502
self.finished.add(.{ .id = id, .failure = failure }) catch unreachable;
503503
backend.uringlator_notify(safety);

0 commit comments

Comments
 (0)