authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-15 12:51:34-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-29 06:20:49-07:00
log10bfbd7d60b721af9bed3f74fa7ab5171471ee46
tree5a41d119a37b7210c9c16c622776ad9f2f0f5a94
parent870a682cd84e49b2213dffd59c9848d7fd12b7a1

std.Io.Threaded: rename from "pool"


2 files changed, 276 insertions(+), 276 deletions(-)

BRANCH_TODO+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1* Threaded: rename Pool to Threaded
2* Threaded: finish linux impl (all tests passing)1* Threaded: finish linux impl (all tests passing)
3* Threaded: finish macos impl 2* Threaded: finish macos impl
4* Threaded: finish windows impl 3* Threaded: finish windows impl
4* Threaded: glibc impl of netLookup
55
6* fix Group.wait not handling cancelation (need to move impl of ResetEvent to Threaded)6* fix Group.wait not handling cancelation (need to move impl of ResetEvent to Threaded)
7* implement cancelRequest for non-linux posix7* implement cancelRequest for non-linux posix
lib/std/Io/Threaded.zig+275-275
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1const Pool = @This();1const Threaded = @This();
22
3const builtin = @import("builtin");3const builtin = @import("builtin");
4const native_os = builtin.os.tag;4const native_os = builtin.os.tag;
...@@ -76,18 +76,18 @@ pub fn init(...@@ -76,18 +76,18 @@ pub fn init(
76 /// If these functions are avoided, then `Allocator.failing` may be passed76 /// If these functions are avoided, then `Allocator.failing` may be passed
77 /// here.77 /// here.
78 gpa: Allocator,78 gpa: Allocator,
79) Pool {79) Threaded {
80 var pool: Pool = .{80 var t: Threaded = .{
81 .allocator = gpa,81 .allocator = gpa,
82 .threads = .empty,82 .threads = .empty,
83 .stack_size = std.Thread.SpawnConfig.default_stack_size,83 .stack_size = std.Thread.SpawnConfig.default_stack_size,
84 .cpu_count = std.Thread.getCpuCount(),84 .cpu_count = std.Thread.getCpuCount(),
85 .concurrent_count = 0,85 .concurrent_count = 0,
86 };86 };
87 if (pool.cpu_count) |n| {87 if (t.cpu_count) |n| {
88 pool.threads.ensureTotalCapacityPrecise(gpa, n - 1) catch {};88 t.threads.ensureTotalCapacityPrecise(gpa, n - 1) catch {};
89 } else |_| {}89 } else |_| {}
90 return pool;90 return t;
91}91}
9292
93/// Statically initialize such that any call to the following functions will93/// Statically initialize such that any call to the following functions will
...@@ -96,7 +96,7 @@ pub fn init(...@@ -96,7 +96,7 @@ pub fn init(
96/// * `Io.VTable.concurrent`96/// * `Io.VTable.concurrent`
97/// * `Io.VTable.groupAsync`97/// * `Io.VTable.groupAsync`
98/// When initialized this way, `deinit` is safe, but unnecessary to call.98/// When initialized this way, `deinit` is safe, but unnecessary to call.
99pub const init_single_threaded: Pool = .{99pub const init_single_threaded: Threaded = .{
100 .allocator = .failing,100 .allocator = .failing,
101 .threads = .empty,101 .threads = .empty,
102 .stack_size = std.Thread.SpawnConfig.default_stack_size,102 .stack_size = std.Thread.SpawnConfig.default_stack_size,
...@@ -104,48 +104,48 @@ pub const init_single_threaded: Pool = .{...@@ -104,48 +104,48 @@ pub const init_single_threaded: Pool = .{
104 .concurrent_count = 0,104 .concurrent_count = 0,
105};105};
106106
107pub fn deinit(pool: *Pool) void {107pub fn deinit(t: *Threaded) void {
108 const gpa = pool.allocator;108 const gpa = t.allocator;
109 pool.join();109 t.join();
110 pool.threads.deinit(gpa);110 t.threads.deinit(gpa);
111 pool.* = undefined;111 t.* = undefined;
112}112}
113113
114fn join(pool: *Pool) void {114fn join(t: *Threaded) void {
115 if (builtin.single_threaded) return;115 if (builtin.single_threaded) return;
116 {116 {
117 pool.mutex.lock();117 t.mutex.lock();
118 defer pool.mutex.unlock();118 defer t.mutex.unlock();
119 pool.join_requested = true;119 t.join_requested = true;
120 }120 }
121 pool.cond.broadcast();121 t.cond.broadcast();
122 for (pool.threads.items) |thread| thread.join();122 for (t.threads.items) |thread| thread.join();
123}123}
124124
125fn worker(pool: *Pool) void {125fn worker(t: *Threaded) void {
126 pool.mutex.lock();126 t.mutex.lock();
127 defer pool.mutex.unlock();127 defer t.mutex.unlock();
128128
129 while (true) {129 while (true) {
130 while (pool.run_queue.popFirst()) |closure_node| {130 while (t.run_queue.popFirst()) |closure_node| {
131 pool.mutex.unlock();131 t.mutex.unlock();
132 const closure: *Closure = @fieldParentPtr("node", closure_node);132 const closure: *Closure = @fieldParentPtr("node", closure_node);
133 const is_concurrent = closure.is_concurrent;133 const is_concurrent = closure.is_concurrent;
134 closure.start(closure);134 closure.start(closure);
135 pool.mutex.lock();135 t.mutex.lock();
136 if (is_concurrent) {136 if (is_concurrent) {
137 // TODO also pop thread and join sometimes137 // TODO also pop thread and join sometimes
138 pool.concurrent_count -= 1;138 t.concurrent_count -= 1;
139 }139 }
140 }140 }
141 if (pool.join_requested) break;141 if (t.join_requested) break;
142 pool.cond.wait(&pool.mutex);142 t.cond.wait(&t.mutex);
143 }143 }
144}144}
145145
146pub fn io(pool: *Pool) Io {146pub fn io(t: *Threaded) Io {
147 return .{147 return .{
148 .userdata = pool,148 .userdata = t,
149 .vtable = &.{149 .vtable = &.{
150 .async = async,150 .async = async,
151 .concurrent = concurrent,151 .concurrent = concurrent,
...@@ -324,14 +324,14 @@ fn async(...@@ -324,14 +324,14 @@ fn async(
324 start(context.ptr, result.ptr);324 start(context.ptr, result.ptr);
325 return null;325 return null;
326 }326 }
327 const pool: *Pool = @ptrCast(@alignCast(userdata));327 const t: *Threaded = @ptrCast(@alignCast(userdata));
328 const cpu_count = pool.cpu_count catch {328 const cpu_count = t.cpu_count catch {
329 return concurrent(userdata, result.len, result_alignment, context, context_alignment, start) catch {329 return concurrent(userdata, result.len, result_alignment, context, context_alignment, start) catch {
330 start(context.ptr, result.ptr);330 start(context.ptr, result.ptr);
331 return null;331 return null;
332 };332 };
333 };333 };
334 const gpa = pool.allocator;334 const gpa = t.allocator;
335 const context_offset = context_alignment.forward(@sizeOf(AsyncClosure));335 const context_offset = context_alignment.forward(@sizeOf(AsyncClosure));
336 const result_offset = result_alignment.forward(context_offset + context.len);336 const result_offset = result_alignment.forward(context_offset + context.len);
337 const n = result_offset + result.len;337 const n = result_offset + result.len;
...@@ -356,38 +356,38 @@ fn async(...@@ -356,38 +356,38 @@ fn async(
356356
357 @memcpy(ac.contextPointer()[0..context.len], context);357 @memcpy(ac.contextPointer()[0..context.len], context);
358358
359 pool.mutex.lock();359 t.mutex.lock();
360360
361 const thread_capacity = cpu_count - 1 + pool.concurrent_count;361 const thread_capacity = cpu_count - 1 + t.concurrent_count;
362362
363 pool.threads.ensureTotalCapacityPrecise(gpa, thread_capacity) catch {363 t.threads.ensureTotalCapacityPrecise(gpa, thread_capacity) catch {
364 pool.mutex.unlock();364 t.mutex.unlock();
365 ac.free(gpa, result.len);365 ac.free(gpa, result.len);
366 start(context.ptr, result.ptr);366 start(context.ptr, result.ptr);
367 return null;367 return null;
368 };368 };
369369
370 pool.run_queue.prepend(&ac.closure.node);370 t.run_queue.prepend(&ac.closure.node);
371371
372 if (pool.threads.items.len < thread_capacity) {372 if (t.threads.items.len < thread_capacity) {
373 const thread = std.Thread.spawn(.{ .stack_size = pool.stack_size }, worker, .{pool}) catch {373 const thread = std.Thread.spawn(.{ .stack_size = t.stack_size }, worker, .{t}) catch {
374 if (pool.threads.items.len == 0) {374 if (t.threads.items.len == 0) {
375 assert(pool.run_queue.popFirst() == &ac.closure.node);375 assert(t.run_queue.popFirst() == &ac.closure.node);
376 pool.mutex.unlock();376 t.mutex.unlock();
377 ac.free(gpa, result.len);377 ac.free(gpa, result.len);
378 start(context.ptr, result.ptr);378 start(context.ptr, result.ptr);
379 return null;379 return null;
380 }380 }
381 // Rely on other workers to do it.381 // Rely on other workers to do it.
382 pool.mutex.unlock();382 t.mutex.unlock();
383 pool.cond.signal();383 t.cond.signal();
384 return @ptrCast(ac);384 return @ptrCast(ac);
385 };385 };
386 pool.threads.appendAssumeCapacity(thread);386 t.threads.appendAssumeCapacity(thread);
387 }387 }
388388
389 pool.mutex.unlock();389 t.mutex.unlock();
390 pool.cond.signal();390 t.cond.signal();
391 return @ptrCast(ac);391 return @ptrCast(ac);
392}392}
393393
...@@ -401,9 +401,9 @@ fn concurrent(...@@ -401,9 +401,9 @@ fn concurrent(
401) error{OutOfMemory}!*Io.AnyFuture {401) error{OutOfMemory}!*Io.AnyFuture {
402 if (builtin.single_threaded) unreachable;402 if (builtin.single_threaded) unreachable;
403403
404 const pool: *Pool = @ptrCast(@alignCast(userdata));404 const t: *Threaded = @ptrCast(@alignCast(userdata));
405 const cpu_count = pool.cpu_count catch 1;405 const cpu_count = t.cpu_count catch 1;
406 const gpa = pool.allocator;406 const gpa = t.allocator;
407 const context_offset = context_alignment.forward(@sizeOf(AsyncClosure));407 const context_offset = context_alignment.forward(@sizeOf(AsyncClosure));
408 const result_offset = result_alignment.forward(context_offset + context.len);408 const result_offset = result_alignment.forward(context_offset + context.len);
409 const n = result_offset + result_len;409 const n = result_offset + result_len;
...@@ -424,37 +424,37 @@ fn concurrent(...@@ -424,37 +424,37 @@ fn concurrent(
424 };424 };
425 @memcpy(ac.contextPointer()[0..context.len], context);425 @memcpy(ac.contextPointer()[0..context.len], context);
426426
427 pool.mutex.lock();427 t.mutex.lock();
428428
429 pool.concurrent_count += 1;429 t.concurrent_count += 1;
430 const thread_capacity = cpu_count - 1 + pool.concurrent_count;430 const thread_capacity = cpu_count - 1 + t.concurrent_count;
431431
432 pool.threads.ensureTotalCapacity(gpa, thread_capacity) catch {432 t.threads.ensureTotalCapacity(gpa, thread_capacity) catch {
433 pool.mutex.unlock();433 t.mutex.unlock();
434 ac.free(gpa, result_len);434 ac.free(gpa, result_len);
435 return error.OutOfMemory;435 return error.OutOfMemory;
436 };436 };
437437
438 pool.run_queue.prepend(&ac.closure.node);438 t.run_queue.prepend(&ac.closure.node);
439439
440 if (pool.threads.items.len < thread_capacity) {440 if (t.threads.items.len < thread_capacity) {
441 const thread = std.Thread.spawn(.{ .stack_size = pool.stack_size }, worker, .{pool}) catch {441 const thread = std.Thread.spawn(.{ .stack_size = t.stack_size }, worker, .{t}) catch {
442 assert(pool.run_queue.popFirst() == &ac.closure.node);442 assert(t.run_queue.popFirst() == &ac.closure.node);
443 pool.mutex.unlock();443 t.mutex.unlock();
444 ac.free(gpa, result_len);444 ac.free(gpa, result_len);
445 return error.OutOfMemory;445 return error.OutOfMemory;
446 };446 };
447 pool.threads.appendAssumeCapacity(thread);447 t.threads.appendAssumeCapacity(thread);
448 }448 }
449449
450 pool.mutex.unlock();450 t.mutex.unlock();
451 pool.cond.signal();451 t.cond.signal();
452 return @ptrCast(ac);452 return @ptrCast(ac);
453}453}
454454
455const GroupClosure = struct {455const GroupClosure = struct {
456 closure: Closure,456 closure: Closure,
457 pool: *Pool,457 t: *Threaded,
458 group: *Io.Group,458 group: *Io.Group,
459 /// Points to sibling `GroupClosure`. Used for walking the group to cancel all.459 /// Points to sibling `GroupClosure`. Used for walking the group to cancel all.
460 node: std.SinglyLinkedList.Node,460 node: std.SinglyLinkedList.Node,
...@@ -515,9 +515,9 @@ fn groupAsync(...@@ -515,9 +515,9 @@ fn groupAsync(
515 start: *const fn (*Io.Group, context: *const anyopaque) void,515 start: *const fn (*Io.Group, context: *const anyopaque) void,
516) void {516) void {
517 if (builtin.single_threaded) return start(context.ptr);517 if (builtin.single_threaded) return start(context.ptr);
518 const pool: *Pool = @ptrCast(@alignCast(userdata));518 const t: *Threaded = @ptrCast(@alignCast(userdata));
519 const cpu_count = pool.cpu_count catch 1;519 const cpu_count = t.cpu_count catch 1;
520 const gpa = pool.allocator;520 const gpa = t.allocator;
521 const n = GroupClosure.contextEnd(context_alignment, context.len);521 const n = GroupClosure.contextEnd(context_alignment, context.len);
522 const gc: *GroupClosure = @ptrCast(@alignCast(gpa.alignedAlloc(u8, .of(GroupClosure), n) catch {522 const gc: *GroupClosure = @ptrCast(@alignCast(gpa.alignedAlloc(u8, .of(GroupClosure), n) catch {
523 return start(group, context.ptr);523 return start(group, context.ptr);
...@@ -528,7 +528,7 @@ fn groupAsync(...@@ -528,7 +528,7 @@ fn groupAsync(
528 .start = GroupClosure.start,528 .start = GroupClosure.start,
529 .is_concurrent = false,529 .is_concurrent = false,
530 },530 },
531 .pool = pool,531 .t = t,
532 .group = group,532 .group = group,
533 .node = undefined,533 .node = undefined,
534 .func = start,534 .func = start,
...@@ -537,30 +537,30 @@ fn groupAsync(...@@ -537,30 +537,30 @@ fn groupAsync(
537 };537 };
538 @memcpy(gc.contextPointer()[0..context.len], context);538 @memcpy(gc.contextPointer()[0..context.len], context);
539539
540 pool.mutex.lock();540 t.mutex.lock();
541541
542 // Append to the group linked list inside the mutex to make `Io.Group.async` thread-safe.542 // Append to the group linked list inside the mutex to make `Io.Group.async` thread-safe.
543 gc.node = .{ .next = @ptrCast(@alignCast(group.token)) };543 gc.node = .{ .next = @ptrCast(@alignCast(group.token)) };
544 group.token = &gc.node;544 group.token = &gc.node;
545545
546 const thread_capacity = cpu_count - 1 + pool.concurrent_count;546 const thread_capacity = cpu_count - 1 + t.concurrent_count;
547547
548 pool.threads.ensureTotalCapacityPrecise(gpa, thread_capacity) catch {548 t.threads.ensureTotalCapacityPrecise(gpa, thread_capacity) catch {
549 pool.mutex.unlock();549 t.mutex.unlock();
550 gc.free(gpa);550 gc.free(gpa);
551 return start(group, context.ptr);551 return start(group, context.ptr);
552 };552 };
553553
554 pool.run_queue.prepend(&gc.closure.node);554 t.run_queue.prepend(&gc.closure.node);
555555
556 if (pool.threads.items.len < thread_capacity) {556 if (t.threads.items.len < thread_capacity) {
557 const thread = std.Thread.spawn(.{ .stack_size = pool.stack_size }, worker, .{pool}) catch {557 const thread = std.Thread.spawn(.{ .stack_size = t.stack_size }, worker, .{t}) catch {
558 assert(pool.run_queue.popFirst() == &gc.closure.node);558 assert(t.run_queue.popFirst() == &gc.closure.node);
559 pool.mutex.unlock();559 t.mutex.unlock();
560 gc.free(gpa);560 gc.free(gpa);
561 return start(group, context.ptr);561 return start(group, context.ptr);
562 };562 };
563 pool.threads.appendAssumeCapacity(thread);563 t.threads.appendAssumeCapacity(thread);
564 }564 }
565565
566 // This needs to be done before unlocking the mutex to avoid a race with566 // This needs to be done before unlocking the mutex to avoid a race with
...@@ -568,13 +568,13 @@ fn groupAsync(...@@ -568,13 +568,13 @@ fn groupAsync(
568 const group_state: *std.atomic.Value(usize) = @ptrCast(&group.state);568 const group_state: *std.atomic.Value(usize) = @ptrCast(&group.state);
569 std.Thread.WaitGroup.startStateless(group_state);569 std.Thread.WaitGroup.startStateless(group_state);
570570
571 pool.mutex.unlock();571 t.mutex.unlock();
572 pool.cond.signal();572 t.cond.signal();
573}573}
574574
575fn groupWait(userdata: ?*anyopaque, group: *Io.Group, token: *anyopaque) void {575fn groupWait(userdata: ?*anyopaque, group: *Io.Group, token: *anyopaque) void {
576 const pool: *Pool = @ptrCast(@alignCast(userdata));576 const t: *Threaded = @ptrCast(@alignCast(userdata));
577 const gpa = pool.allocator;577 const gpa = t.allocator;
578578
579 if (builtin.single_threaded) return;579 if (builtin.single_threaded) return;
580580
...@@ -593,8 +593,8 @@ fn groupWait(userdata: ?*anyopaque, group: *Io.Group, token: *anyopaque) void {...@@ -593,8 +593,8 @@ fn groupWait(userdata: ?*anyopaque, group: *Io.Group, token: *anyopaque) void {
593}593}
594594
595fn groupCancel(userdata: ?*anyopaque, group: *Io.Group, token: *anyopaque) void {595fn groupCancel(userdata: ?*anyopaque, group: *Io.Group, token: *anyopaque) void {
596 const pool: *Pool = @ptrCast(@alignCast(userdata));596 const t: *Threaded = @ptrCast(@alignCast(userdata));
597 const gpa = pool.allocator;597 const gpa = t.allocator;
598598
599 if (builtin.single_threaded) return;599 if (builtin.single_threaded) return;
600600
...@@ -629,9 +629,9 @@ fn await(...@@ -629,9 +629,9 @@ fn await(
629 result_alignment: std.mem.Alignment,629 result_alignment: std.mem.Alignment,
630) void {630) void {
631 _ = result_alignment;631 _ = result_alignment;
632 const pool: *Pool = @ptrCast(@alignCast(userdata));632 const t: *Threaded = @ptrCast(@alignCast(userdata));
633 const closure: *AsyncClosure = @ptrCast(@alignCast(any_future));633 const closure: *AsyncClosure = @ptrCast(@alignCast(any_future));
634 closure.waitAndFree(pool.allocator, result);634 closure.waitAndFree(t.allocator, result);
635}635}
636636
637fn cancel(637fn cancel(
...@@ -641,31 +641,31 @@ fn cancel(...@@ -641,31 +641,31 @@ fn cancel(
641 result_alignment: std.mem.Alignment,641 result_alignment: std.mem.Alignment,
642) void {642) void {
643 _ = result_alignment;643 _ = result_alignment;
644 const pool: *Pool = @ptrCast(@alignCast(userdata));644 const t: *Threaded = @ptrCast(@alignCast(userdata));
645 const ac: *AsyncClosure = @ptrCast(@alignCast(any_future));645 const ac: *AsyncClosure = @ptrCast(@alignCast(any_future));
646 ac.closure.requestCancel();646 ac.closure.requestCancel();
647 ac.waitAndFree(pool.allocator, result);647 ac.waitAndFree(t.allocator, result);
648}648}
649649
650fn cancelRequested(userdata: ?*anyopaque) bool {650fn cancelRequested(userdata: ?*anyopaque) bool {
651 const pool: *Pool = @ptrCast(@alignCast(userdata));651 const t: *Threaded = @ptrCast(@alignCast(userdata));
652 _ = pool;652 _ = t;
653 const closure = current_closure orelse return false;653 const closure = current_closure orelse return false;
654 return @atomicLoad(std.Thread.Id, &closure.cancel_tid, .acquire) == Closure.canceling_tid;654 return @atomicLoad(std.Thread.Id, &closure.cancel_tid, .acquire) == Closure.canceling_tid;
655}655}
656656
657fn checkCancel(pool: *Pool) error{Canceled}!void {657fn checkCancel(t: *Threaded) error{Canceled}!void {
658 if (cancelRequested(pool)) return error.Canceled;658 if (cancelRequested(t)) return error.Canceled;
659}659}
660660
661fn mutexLock(userdata: ?*anyopaque, prev_state: Io.Mutex.State, mutex: *Io.Mutex) Io.Cancelable!void {661fn mutexLock(userdata: ?*anyopaque, prev_state: Io.Mutex.State, mutex: *Io.Mutex) Io.Cancelable!void {
662 const pool: *Pool = @ptrCast(@alignCast(userdata));662 const t: *Threaded = @ptrCast(@alignCast(userdata));
663 if (prev_state == .contended) {663 if (prev_state == .contended) {
664 try pool.checkCancel();664 try t.checkCancel();
665 futexWait(@ptrCast(&mutex.state), @intFromEnum(Io.Mutex.State.contended));665 futexWait(@ptrCast(&mutex.state), @intFromEnum(Io.Mutex.State.contended));
666 }666 }
667 while (@atomicRmw(Io.Mutex.State, &mutex.state, .Xchg, .contended, .acquire) != .unlocked) {667 while (@atomicRmw(Io.Mutex.State, &mutex.state, .Xchg, .contended, .acquire) != .unlocked) {
668 try pool.checkCancel();668 try t.checkCancel();
669 futexWait(@ptrCast(&mutex.state), @intFromEnum(Io.Mutex.State.contended));669 futexWait(@ptrCast(&mutex.state), @intFromEnum(Io.Mutex.State.contended));
670 }670 }
671}671}
...@@ -689,8 +689,8 @@ fn mutexUnlock(userdata: ?*anyopaque, prev_state: Io.Mutex.State, mutex: *Io.Mut...@@ -689,8 +689,8 @@ fn mutexUnlock(userdata: ?*anyopaque, prev_state: Io.Mutex.State, mutex: *Io.Mut
689}689}
690690
691fn conditionWaitUncancelable(userdata: ?*anyopaque, cond: *Io.Condition, mutex: *Io.Mutex) void {691fn conditionWaitUncancelable(userdata: ?*anyopaque, cond: *Io.Condition, mutex: *Io.Mutex) void {
692 const pool: *Pool = @ptrCast(@alignCast(userdata));692 const t: *Threaded = @ptrCast(@alignCast(userdata));
693 const pool_io = pool.io();693 const t_io = t.io();
694 comptime assert(@TypeOf(cond.state) == u64);694 comptime assert(@TypeOf(cond.state) == u64);
695 const ints: *[2]std.atomic.Value(u32) = @ptrCast(&cond.state);695 const ints: *[2]std.atomic.Value(u32) = @ptrCast(&cond.state);
696 const cond_state = &ints[0];696 const cond_state = &ints[0];
...@@ -704,8 +704,8 @@ fn conditionWaitUncancelable(userdata: ?*anyopaque, cond: *Io.Condition, mutex:...@@ -704,8 +704,8 @@ fn conditionWaitUncancelable(userdata: ?*anyopaque, cond: *Io.Condition, mutex:
704 assert(state & waiter_mask != waiter_mask);704 assert(state & waiter_mask != waiter_mask);
705 state += one_waiter;705 state += one_waiter;
706706
707 mutex.unlock(pool_io);707 mutex.unlock(t_io);
708 defer mutex.lockUncancelable(pool_io);708 defer mutex.lockUncancelable(t_io);
709709
710 while (true) {710 while (true) {
711 futexWait(cond_epoch, epoch);711 futexWait(cond_epoch, epoch);
...@@ -719,7 +719,7 @@ fn conditionWaitUncancelable(userdata: ?*anyopaque, cond: *Io.Condition, mutex:...@@ -719,7 +719,7 @@ fn conditionWaitUncancelable(userdata: ?*anyopaque, cond: *Io.Condition, mutex:
719}719}
720720
721fn conditionWait(userdata: ?*anyopaque, cond: *Io.Condition, mutex: *Io.Mutex) Io.Cancelable!void {721fn conditionWait(userdata: ?*anyopaque, cond: *Io.Condition, mutex: *Io.Mutex) Io.Cancelable!void {
722 const pool: *Pool = @ptrCast(@alignCast(userdata));722 const t: *Threaded = @ptrCast(@alignCast(userdata));
723 comptime assert(@TypeOf(cond.state) == u64);723 comptime assert(@TypeOf(cond.state) == u64);
724 const ints: *[2]std.atomic.Value(u32) = @ptrCast(&cond.state);724 const ints: *[2]std.atomic.Value(u32) = @ptrCast(&cond.state);
725 const cond_state = &ints[0];725 const cond_state = &ints[0];
...@@ -743,11 +743,11 @@ fn conditionWait(userdata: ?*anyopaque, cond: *Io.Condition, mutex: *Io.Mutex) I...@@ -743,11 +743,11 @@ fn conditionWait(userdata: ?*anyopaque, cond: *Io.Condition, mutex: *Io.Mutex) I
743 assert(state & waiter_mask != waiter_mask);743 assert(state & waiter_mask != waiter_mask);
744 state += one_waiter;744 state += one_waiter;
745745
746 mutex.unlock(pool.io());746 mutex.unlock(t.io());
747 defer mutex.lockUncancelable(pool.io());747 defer mutex.lockUncancelable(t.io());
748748
749 while (true) {749 while (true) {
750 try pool.checkCancel();750 try t.checkCancel();
751 futexWait(cond_epoch, epoch);751 futexWait(cond_epoch, epoch);
752752
753 epoch = cond_epoch.load(.acquire);753 epoch = cond_epoch.load(.acquire);
...@@ -764,8 +764,8 @@ fn conditionWait(userdata: ?*anyopaque, cond: *Io.Condition, mutex: *Io.Mutex) I...@@ -764,8 +764,8 @@ fn conditionWait(userdata: ?*anyopaque, cond: *Io.Condition, mutex: *Io.Mutex) I
764}764}
765765
766fn conditionWake(userdata: ?*anyopaque, cond: *Io.Condition, wake: Io.Condition.Wake) void {766fn conditionWake(userdata: ?*anyopaque, cond: *Io.Condition, wake: Io.Condition.Wake) void {
767 const pool: *Pool = @ptrCast(@alignCast(userdata));767 const t: *Threaded = @ptrCast(@alignCast(userdata));
768 _ = pool;768 _ = t;
769 comptime assert(@TypeOf(cond.state) == u64);769 comptime assert(@TypeOf(cond.state) == u64);
770 const ints: *[2]std.atomic.Value(u32) = @ptrCast(&cond.state);770 const ints: *[2]std.atomic.Value(u32) = @ptrCast(&cond.state);
771 const cond_state = &ints[0];771 const cond_state = &ints[0];
...@@ -825,13 +825,13 @@ fn conditionWake(userdata: ?*anyopaque, cond: *Io.Condition, wake: Io.Condition....@@ -825,13 +825,13 @@ fn conditionWake(userdata: ?*anyopaque, cond: *Io.Condition, wake: Io.Condition.
825}825}
826826
827fn dirMakePosix(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode: Io.Dir.Mode) Io.Dir.MakeError!void {827fn dirMakePosix(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode: Io.Dir.Mode) Io.Dir.MakeError!void {
828 const pool: *Pool = @ptrCast(@alignCast(userdata));828 const t: *Threaded = @ptrCast(@alignCast(userdata));
829829
830 var path_buffer: [posix.PATH_MAX]u8 = undefined;830 var path_buffer: [posix.PATH_MAX]u8 = undefined;
831 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);831 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
832832
833 while (true) {833 while (true) {
834 try pool.checkCancel();834 try t.checkCancel();
835 switch (posix.errno(posix.system.mkdirat(dir.handle, sub_path_posix, mode))) {835 switch (posix.errno(posix.system.mkdirat(dir.handle, sub_path_posix, mode))) {
836 .SUCCESS => return,836 .SUCCESS => return,
837 .INTR => continue,837 .INTR => continue,
...@@ -858,8 +858,8 @@ fn dirMakePosix(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode:...@@ -858,8 +858,8 @@ fn dirMakePosix(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode:
858}858}
859859
860fn dirStat(userdata: ?*anyopaque, dir: Io.Dir) Io.Dir.StatError!Io.Dir.Stat {860fn dirStat(userdata: ?*anyopaque, dir: Io.Dir) Io.Dir.StatError!Io.Dir.Stat {
861 const pool: *Pool = @ptrCast(@alignCast(userdata));861 const t: *Threaded = @ptrCast(@alignCast(userdata));
862 try pool.checkCancel();862 try t.checkCancel();
863863
864 _ = dir;864 _ = dir;
865 @panic("TODO");865 @panic("TODO");
...@@ -871,7 +871,7 @@ fn dirStatPathLinux(...@@ -871,7 +871,7 @@ fn dirStatPathLinux(
871 sub_path: []const u8,871 sub_path: []const u8,
872 options: Io.Dir.StatPathOptions,872 options: Io.Dir.StatPathOptions,
873) Io.Dir.StatPathError!Io.File.Stat {873) Io.Dir.StatPathError!Io.File.Stat {
874 const pool: *Pool = @ptrCast(@alignCast(userdata));874 const t: *Threaded = @ptrCast(@alignCast(userdata));
875 const linux = std.os.linux;875 const linux = std.os.linux;
876876
877 var path_buffer: [posix.PATH_MAX]u8 = undefined;877 var path_buffer: [posix.PATH_MAX]u8 = undefined;
...@@ -881,7 +881,7 @@ fn dirStatPathLinux(...@@ -881,7 +881,7 @@ fn dirStatPathLinux(
881 @as(u32, if (!options.follow_symlinks) linux.AT.SYMLINK_NOFOLLOW else 0);881 @as(u32, if (!options.follow_symlinks) linux.AT.SYMLINK_NOFOLLOW else 0);
882882
883 while (true) {883 while (true) {
884 try pool.checkCancel();884 try t.checkCancel();
885 var statx = std.mem.zeroes(linux.Statx);885 var statx = std.mem.zeroes(linux.Statx);
886 const rc = linux.statx(886 const rc = linux.statx(
887 dir.handle,887 dir.handle,
...@@ -913,7 +913,7 @@ fn dirStatPathPosix(...@@ -913,7 +913,7 @@ fn dirStatPathPosix(
913 sub_path: []const u8,913 sub_path: []const u8,
914 options: Io.Dir.StatPathOptions,914 options: Io.Dir.StatPathOptions,
915) Io.Dir.StatPathError!Io.File.Stat {915) Io.Dir.StatPathError!Io.File.Stat {
916 const pool: *Pool = @ptrCast(@alignCast(userdata));916 const t: *Threaded = @ptrCast(@alignCast(userdata));
917917
918 var path_buffer: [posix.PATH_MAX]u8 = undefined;918 var path_buffer: [posix.PATH_MAX]u8 = undefined;
919 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);919 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
...@@ -921,7 +921,7 @@ fn dirStatPathPosix(...@@ -921,7 +921,7 @@ fn dirStatPathPosix(
921 const flags: u32 = if (!options.follow_symlinks) posix.AT.SYMLINK_NOFOLLOW else 0;921 const flags: u32 = if (!options.follow_symlinks) posix.AT.SYMLINK_NOFOLLOW else 0;
922922
923 while (true) {923 while (true) {
924 try pool.checkCancel();924 try t.checkCancel();
925 var stat = std.mem.zeroes(posix.Stat);925 var stat = std.mem.zeroes(posix.Stat);
926 switch (posix.errno(fstatat_sym(dir.handle, sub_path_posix, &stat, flags))) {926 switch (posix.errno(fstatat_sym(dir.handle, sub_path_posix, &stat, flags))) {
927 .SUCCESS => return statFromPosix(stat),927 .SUCCESS => return statFromPosix(stat),
...@@ -943,12 +943,12 @@ fn dirStatPathPosix(...@@ -943,12 +943,12 @@ fn dirStatPathPosix(
943}943}
944944
945fn fileStatPosix(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat {945fn fileStatPosix(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat {
946 const pool: *Pool = @ptrCast(@alignCast(userdata));946 const t: *Threaded = @ptrCast(@alignCast(userdata));
947947
948 if (posix.Stat == void) return error.Streaming;948 if (posix.Stat == void) return error.Streaming;
949949
950 while (true) {950 while (true) {
951 try pool.checkCancel();951 try t.checkCancel();
952 var stat = std.mem.zeroes(posix.Stat);952 var stat = std.mem.zeroes(posix.Stat);
953 switch (posix.errno(fstat_sym(file.handle, &stat))) {953 switch (posix.errno(fstat_sym(file.handle, &stat))) {
954 .SUCCESS => return statFromPosix(&stat),954 .SUCCESS => return statFromPosix(&stat),
...@@ -963,10 +963,10 @@ fn fileStatPosix(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File...@@ -963,10 +963,10 @@ fn fileStatPosix(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File
963}963}
964964
965fn fileStatLinux(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat {965fn fileStatLinux(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat {
966 const pool: *Pool = @ptrCast(@alignCast(userdata));966 const t: *Threaded = @ptrCast(@alignCast(userdata));
967 const linux = std.os.linux;967 const linux = std.os.linux;
968 while (true) {968 while (true) {
969 try pool.checkCancel();969 try t.checkCancel();
970 var statx = std.mem.zeroes(linux.Statx);970 var statx = std.mem.zeroes(linux.Statx);
971 const rc = linux.statx(971 const rc = linux.statx(
972 file.handle,972 file.handle,
...@@ -993,17 +993,17 @@ fn fileStatLinux(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File...@@ -993,17 +993,17 @@ fn fileStatLinux(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File
993}993}
994994
995fn fileStatWindows(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat {995fn fileStatWindows(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat {
996 const pool: *Pool = @ptrCast(@alignCast(userdata));996 const t: *Threaded = @ptrCast(@alignCast(userdata));
997 try pool.checkCancel();997 try t.checkCancel();
998 _ = file;998 _ = file;
999 @panic("TODO");999 @panic("TODO");
1000}1000}
10011001
1002fn fileStatWasi(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat {1002fn fileStatWasi(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat {
1003 if (builtin.link_libc) return fileStatPosix(userdata, file);1003 if (builtin.link_libc) return fileStatPosix(userdata, file);
1004 const pool: *Pool = @ptrCast(@alignCast(userdata));1004 const t: *Threaded = @ptrCast(@alignCast(userdata));
1005 while (true) {1005 while (true) {
1006 try pool.checkCancel();1006 try t.checkCancel();
1007 var stat: std.os.wasi.filestat_t = undefined;1007 var stat: std.os.wasi.filestat_t = undefined;
1008 switch (std.os.wasi.fd_filestat_get(file.handle, &stat)) {1008 switch (std.os.wasi.fd_filestat_get(file.handle, &stat)) {
1009 .SUCCESS => return statFromWasi(&stat),1009 .SUCCESS => return statFromWasi(&stat),
...@@ -1031,7 +1031,7 @@ fn dirCreateFilePosix(...@@ -1031,7 +1031,7 @@ fn dirCreateFilePosix(
1031 sub_path: []const u8,1031 sub_path: []const u8,
1032 flags: Io.File.CreateFlags,1032 flags: Io.File.CreateFlags,
1033) Io.File.OpenError!Io.File {1033) Io.File.OpenError!Io.File {
1034 const pool: *Pool = @ptrCast(@alignCast(userdata));1034 const t: *Threaded = @ptrCast(@alignCast(userdata));
10351035
1036 var path_buffer: [posix.PATH_MAX]u8 = undefined;1036 var path_buffer: [posix.PATH_MAX]u8 = undefined;
1037 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);1037 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
...@@ -1062,7 +1062,7 @@ fn dirCreateFilePosix(...@@ -1062,7 +1062,7 @@ fn dirCreateFilePosix(
1062 };1062 };
10631063
1064 const fd: posix.fd_t = while (true) {1064 const fd: posix.fd_t = while (true) {
1065 try pool.checkCancel();1065 try t.checkCancel();
1066 const rc = openat_sym(dir.handle, sub_path_posix, os_flags, flags.mode);1066 const rc = openat_sym(dir.handle, sub_path_posix, os_flags, flags.mode);
1067 switch (posix.errno(rc)) {1067 switch (posix.errno(rc)) {
1068 .SUCCESS => break @intCast(rc),1068 .SUCCESS => break @intCast(rc),
...@@ -1106,7 +1106,7 @@ fn dirCreateFilePosix(...@@ -1106,7 +1106,7 @@ fn dirCreateFilePosix(
1106 .exclusive => posix.LOCK.EX | lock_nonblocking,1106 .exclusive => posix.LOCK.EX | lock_nonblocking,
1107 };1107 };
1108 while (true) {1108 while (true) {
1109 try pool.checkCancel();1109 try t.checkCancel();
1110 switch (posix.errno(posix.system.flock(fd, lock_flags))) {1110 switch (posix.errno(posix.system.flock(fd, lock_flags))) {
1111 .SUCCESS => break,1111 .SUCCESS => break,
1112 .INTR => continue,1112 .INTR => continue,
...@@ -1123,7 +1123,7 @@ fn dirCreateFilePosix(...@@ -1123,7 +1123,7 @@ fn dirCreateFilePosix(
11231123
1124 if (has_flock_open_flags and flags.lock_nonblocking) {1124 if (has_flock_open_flags and flags.lock_nonblocking) {
1125 var fl_flags: usize = while (true) {1125 var fl_flags: usize = while (true) {
1126 try pool.checkCancel();1126 try t.checkCancel();
1127 switch (posix.errno(posix.system.fcntl(fd, posix.F.GETFL, 0))) {1127 switch (posix.errno(posix.system.fcntl(fd, posix.F.GETFL, 0))) {
1128 .SUCCESS => break,1128 .SUCCESS => break,
1129 .INTR => continue,1129 .INTR => continue,
...@@ -1132,7 +1132,7 @@ fn dirCreateFilePosix(...@@ -1132,7 +1132,7 @@ fn dirCreateFilePosix(
1132 };1132 };
1133 fl_flags &= ~@as(usize, 1 << @bitOffsetOf(posix.O, "NONBLOCK"));1133 fl_flags &= ~@as(usize, 1 << @bitOffsetOf(posix.O, "NONBLOCK"));
1134 while (true) {1134 while (true) {
1135 try pool.checkCancel();1135 try t.checkCancel();
1136 switch (posix.errno(posix.fcntl(fd, posix.F.SETFL, fl_flags))) {1136 switch (posix.errno(posix.fcntl(fd, posix.F.SETFL, fl_flags))) {
1137 .SUCCESS => break,1137 .SUCCESS => break,
1138 .INTR => continue,1138 .INTR => continue,
...@@ -1150,7 +1150,7 @@ fn dirOpenFile(...@@ -1150,7 +1150,7 @@ fn dirOpenFile(
1150 sub_path: []const u8,1150 sub_path: []const u8,
1151 flags: Io.File.OpenFlags,1151 flags: Io.File.OpenFlags,
1152) Io.File.OpenError!Io.File {1152) Io.File.OpenError!Io.File {
1153 const pool: *Pool = @ptrCast(@alignCast(userdata));1153 const t: *Threaded = @ptrCast(@alignCast(userdata));
11541154
1155 var path_buffer: [posix.PATH_MAX]u8 = undefined;1155 var path_buffer: [posix.PATH_MAX]u8 = undefined;
1156 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);1156 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
...@@ -1191,7 +1191,7 @@ fn dirOpenFile(...@@ -1191,7 +1191,7 @@ fn dirOpenFile(
1191 }1191 }
1192 }1192 }
1193 const fd: posix.fd_t = while (true) {1193 const fd: posix.fd_t = while (true) {
1194 try pool.checkCancel();1194 try t.checkCancel();
1195 const rc = openat_sym(dir.handle, sub_path_posix, os_flags, @as(posix.mode_t, 0));1195 const rc = openat_sym(dir.handle, sub_path_posix, os_flags, @as(posix.mode_t, 0));
1196 switch (posix.errno(rc)) {1196 switch (posix.errno(rc)) {
1197 .SUCCESS => break @intCast(rc),1197 .SUCCESS => break @intCast(rc),
...@@ -1235,7 +1235,7 @@ fn dirOpenFile(...@@ -1235,7 +1235,7 @@ fn dirOpenFile(
1235 .exclusive => posix.LOCK.EX | lock_nonblocking,1235 .exclusive => posix.LOCK.EX | lock_nonblocking,
1236 };1236 };
1237 while (true) {1237 while (true) {
1238 try pool.checkCancel();1238 try t.checkCancel();
1239 switch (posix.errno(posix.system.flock(fd, lock_flags))) {1239 switch (posix.errno(posix.system.flock(fd, lock_flags))) {
1240 .SUCCESS => break,1240 .SUCCESS => break,
1241 .INTR => continue,1241 .INTR => continue,
...@@ -1252,7 +1252,7 @@ fn dirOpenFile(...@@ -1252,7 +1252,7 @@ fn dirOpenFile(
12521252
1253 if (has_flock_open_flags and flags.lock_nonblocking) {1253 if (has_flock_open_flags and flags.lock_nonblocking) {
1254 var fl_flags: usize = while (true) {1254 var fl_flags: usize = while (true) {
1255 try pool.checkCancel();1255 try t.checkCancel();
1256 switch (posix.errno(posix.system.fcntl(fd, posix.F.GETFL, 0))) {1256 switch (posix.errno(posix.system.fcntl(fd, posix.F.GETFL, 0))) {
1257 .SUCCESS => break,1257 .SUCCESS => break,
1258 .INTR => continue,1258 .INTR => continue,
...@@ -1261,7 +1261,7 @@ fn dirOpenFile(...@@ -1261,7 +1261,7 @@ fn dirOpenFile(
1261 };1261 };
1262 fl_flags &= ~@as(usize, 1 << @bitOffsetOf(posix.O, "NONBLOCK"));1262 fl_flags &= ~@as(usize, 1 << @bitOffsetOf(posix.O, "NONBLOCK"));
1263 while (true) {1263 while (true) {
1264 try pool.checkCancel();1264 try t.checkCancel();
1265 switch (posix.errno(posix.fcntl(fd, posix.F.SETFL, fl_flags))) {1265 switch (posix.errno(posix.fcntl(fd, posix.F.SETFL, fl_flags))) {
1266 .SUCCESS => break,1266 .SUCCESS => break,
1267 .INTR => continue,1267 .INTR => continue,
...@@ -1274,13 +1274,13 @@ fn dirOpenFile(...@@ -1274,13 +1274,13 @@ fn dirOpenFile(
1274}1274}
12751275
1276fn fileClose(userdata: ?*anyopaque, file: Io.File) void {1276fn fileClose(userdata: ?*anyopaque, file: Io.File) void {
1277 const pool: *Pool = @ptrCast(@alignCast(userdata));1277 const t: *Threaded = @ptrCast(@alignCast(userdata));
1278 _ = pool;1278 _ = t;
1279 posix.close(file.handle);1279 posix.close(file.handle);
1280}1280}
12811281
1282fn fileReadStreaming(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File.ReadStreamingError!usize {1282fn fileReadStreaming(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File.ReadStreamingError!usize {
1283 const pool: *Pool = @ptrCast(@alignCast(userdata));1283 const t: *Threaded = @ptrCast(@alignCast(userdata));
12841284
1285 if (is_windows) {1285 if (is_windows) {
1286 const DWORD = windows.DWORD;1286 const DWORD = windows.DWORD;
...@@ -1288,7 +1288,7 @@ fn fileReadStreaming(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File...@@ -1288,7 +1288,7 @@ fn fileReadStreaming(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File
1288 var truncate: usize = 0;1288 var truncate: usize = 0;
1289 var total: usize = 0;1289 var total: usize = 0;
1290 while (index < data.len) {1290 while (index < data.len) {
1291 try pool.checkCancel();1291 try t.checkCancel();
1292 {1292 {
1293 const untruncated = data[index];1293 const untruncated = data[index];
1294 data[index] = untruncated[truncate..];1294 data[index] = untruncated[truncate..];
...@@ -1333,7 +1333,7 @@ fn fileReadStreaming(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File...@@ -1333,7 +1333,7 @@ fn fileReadStreaming(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File
1333 assert(dest[0].len > 0);1333 assert(dest[0].len > 0);
13341334
1335 if (native_os == .wasi and !builtin.link_libc) while (true) {1335 if (native_os == .wasi and !builtin.link_libc) while (true) {
1336 try pool.checkCancel();1336 try t.checkCancel();
1337 var nread: usize = undefined;1337 var nread: usize = undefined;
1338 switch (std.os.wasi.fd_read(file.handle, dest.ptr, dest.len, &nread)) {1338 switch (std.os.wasi.fd_read(file.handle, dest.ptr, dest.len, &nread)) {
1339 .SUCCESS => return nread,1339 .SUCCESS => return nread,
...@@ -1354,7 +1354,7 @@ fn fileReadStreaming(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File...@@ -1354,7 +1354,7 @@ fn fileReadStreaming(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File
1354 };1354 };
13551355
1356 while (true) {1356 while (true) {
1357 try pool.checkCancel();1357 try t.checkCancel();
1358 const rc = posix.system.readv(file.handle, dest.ptr, @intCast(dest.len));1358 const rc = posix.system.readv(file.handle, dest.ptr, @intCast(dest.len));
1359 switch (posix.errno(rc)) {1359 switch (posix.errno(rc)) {
1360 .SUCCESS => return @intCast(rc),1360 .SUCCESS => return @intCast(rc),
...@@ -1377,7 +1377,7 @@ fn fileReadStreaming(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File...@@ -1377,7 +1377,7 @@ fn fileReadStreaming(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File
1377}1377}
13781378
1379fn fileReadPositional(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset: u64) Io.File.ReadPositionalError!usize {1379fn fileReadPositional(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset: u64) Io.File.ReadPositionalError!usize {
1380 const pool: *Pool = @ptrCast(@alignCast(userdata));1380 const t: *Threaded = @ptrCast(@alignCast(userdata));
13811381
1382 if (is_windows) {1382 if (is_windows) {
1383 const DWORD = windows.DWORD;1383 const DWORD = windows.DWORD;
...@@ -1386,7 +1386,7 @@ fn fileReadPositional(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset...@@ -1386,7 +1386,7 @@ fn fileReadPositional(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset
1386 var truncate: usize = 0;1386 var truncate: usize = 0;
1387 var total: usize = 0;1387 var total: usize = 0;
1388 while (true) {1388 while (true) {
1389 try pool.checkCancel();1389 try t.checkCancel();
1390 {1390 {
1391 const untruncated = data[index];1391 const untruncated = data[index];
1392 data[index] = untruncated[truncate..];1392 data[index] = untruncated[truncate..];
...@@ -1454,7 +1454,7 @@ fn fileReadPositional(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset...@@ -1454,7 +1454,7 @@ fn fileReadPositional(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset
1454 assert(dest[0].len > 0);1454 assert(dest[0].len > 0);
14551455
1456 if (native_os == .wasi and !builtin.link_libc) while (true) {1456 if (native_os == .wasi and !builtin.link_libc) while (true) {
1457 try pool.checkCancel();1457 try t.checkCancel();
1458 var nread: usize = undefined;1458 var nread: usize = undefined;
1459 switch (std.os.wasi.fd_pread(file.handle, dest.ptr, dest.len, offset, &nread)) {1459 switch (std.os.wasi.fd_pread(file.handle, dest.ptr, dest.len, offset, &nread)) {
1460 .SUCCESS => return nread,1460 .SUCCESS => return nread,
...@@ -1479,7 +1479,7 @@ fn fileReadPositional(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset...@@ -1479,7 +1479,7 @@ fn fileReadPositional(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset
1479 };1479 };
14801480
1481 while (true) {1481 while (true) {
1482 try pool.checkCancel();1482 try t.checkCancel();
1483 const rc = preadv_sym(file.handle, dest.ptr, @intCast(dest.len), @bitCast(offset));1483 const rc = preadv_sym(file.handle, dest.ptr, @intCast(dest.len), @bitCast(offset));
1484 switch (posix.errno(rc)) {1484 switch (posix.errno(rc)) {
1485 .SUCCESS => return @bitCast(rc),1485 .SUCCESS => return @bitCast(rc),
...@@ -1505,8 +1505,8 @@ fn fileReadPositional(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset...@@ -1505,8 +1505,8 @@ fn fileReadPositional(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset
1505}1505}
15061506
1507fn fileSeekBy(userdata: ?*anyopaque, file: Io.File, offset: i64) Io.File.SeekError!void {1507fn fileSeekBy(userdata: ?*anyopaque, file: Io.File, offset: i64) Io.File.SeekError!void {
1508 const pool: *Pool = @ptrCast(@alignCast(userdata));1508 const t: *Threaded = @ptrCast(@alignCast(userdata));
1509 try pool.checkCancel();1509 try t.checkCancel();
15101510
1511 _ = file;1511 _ = file;
1512 _ = offset;1512 _ = offset;
...@@ -1514,11 +1514,11 @@ fn fileSeekBy(userdata: ?*anyopaque, file: Io.File, offset: i64) Io.File.SeekErr...@@ -1514,11 +1514,11 @@ fn fileSeekBy(userdata: ?*anyopaque, file: Io.File, offset: i64) Io.File.SeekErr
1514}1514}
15151515
1516fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekError!void {1516fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekError!void {
1517 const pool: *Pool = @ptrCast(@alignCast(userdata));1517 const t: *Threaded = @ptrCast(@alignCast(userdata));
1518 const fd = file.handle;1518 const fd = file.handle;
15191519
1520 if (native_os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) while (true) {1520 if (native_os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) while (true) {
1521 try pool.checkCancel();1521 try t.checkCancel();
1522 var result: u64 = undefined;1522 var result: u64 = undefined;
1523 switch (posix.errno(posix.system.llseek(fd, offset, &result, posix.SEEK.SET))) {1523 switch (posix.errno(posix.system.llseek(fd, offset, &result, posix.SEEK.SET))) {
1524 .SUCCESS => return,1524 .SUCCESS => return,
...@@ -1533,12 +1533,12 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr...@@ -1533,12 +1533,12 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
1533 };1533 };
15341534
1535 if (native_os == .windows) {1535 if (native_os == .windows) {
1536 try pool.checkCancel();1536 try t.checkCancel();
1537 return windows.SetFilePointerEx_BEGIN(fd, offset);1537 return windows.SetFilePointerEx_BEGIN(fd, offset);
1538 }1538 }
15391539
1540 if (native_os == .wasi and !builtin.link_libc) while (true) {1540 if (native_os == .wasi and !builtin.link_libc) while (true) {
1541 try pool.checkCancel();1541 try t.checkCancel();
1542 var new_offset: std.os.wasi.filesize_t = undefined;1542 var new_offset: std.os.wasi.filesize_t = undefined;
1543 switch (std.os.wasi.fd_seek(fd, @bitCast(offset), .SET, &new_offset)) {1543 switch (std.os.wasi.fd_seek(fd, @bitCast(offset), .SET, &new_offset)) {
1544 .SUCCESS => return,1544 .SUCCESS => return,
...@@ -1556,7 +1556,7 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr...@@ -1556,7 +1556,7 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
1556 if (posix.SEEK == void) return error.Unseekable;1556 if (posix.SEEK == void) return error.Unseekable;
15571557
1558 while (true) {1558 while (true) {
1559 try pool.checkCancel();1559 try t.checkCancel();
1560 switch (posix.errno(lseek_sym(fd, @bitCast(offset), posix.SEEK.SET))) {1560 switch (posix.errno(lseek_sym(fd, @bitCast(offset), posix.SEEK.SET))) {
1561 .SUCCESS => return,1561 .SUCCESS => return,
1562 .INTR => continue,1562 .INTR => continue,
...@@ -1571,8 +1571,8 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr...@@ -1571,8 +1571,8 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
1571}1571}
15721572
1573fn pwrite(userdata: ?*anyopaque, file: Io.File, buffer: []const u8, offset: posix.off_t) Io.File.PWriteError!usize {1573fn pwrite(userdata: ?*anyopaque, file: Io.File, buffer: []const u8, offset: posix.off_t) Io.File.PWriteError!usize {
1574 const pool: *Pool = @ptrCast(@alignCast(userdata));1574 const t: *Threaded = @ptrCast(@alignCast(userdata));
1575 try pool.checkCancel();1575 try t.checkCancel();
1576 const fs_file: std.fs.File = .{ .handle = file.handle };1576 const fs_file: std.fs.File = .{ .handle = file.handle };
1577 return switch (offset) {1577 return switch (offset) {
1578 -1 => fs_file.write(buffer),1578 -1 => fs_file.write(buffer),
...@@ -1581,8 +1581,8 @@ fn pwrite(userdata: ?*anyopaque, file: Io.File, buffer: []const u8, offset: posi...@@ -1581,8 +1581,8 @@ fn pwrite(userdata: ?*anyopaque, file: Io.File, buffer: []const u8, offset: posi
1581}1581}
15821582
1583fn nowPosix(userdata: ?*anyopaque, clock: Io.Clock) Io.Clock.Error!Io.Timestamp {1583fn nowPosix(userdata: ?*anyopaque, clock: Io.Clock) Io.Clock.Error!Io.Timestamp {
1584 const pool: *Pool = @ptrCast(@alignCast(userdata));1584 const t: *Threaded = @ptrCast(@alignCast(userdata));
1585 _ = pool;1585 _ = t;
1586 const clock_id: posix.clockid_t = clockToPosix(clock);1586 const clock_id: posix.clockid_t = clockToPosix(clock);
1587 var tp: posix.timespec = undefined;1587 var tp: posix.timespec = undefined;
1588 switch (posix.errno(posix.system.clock_gettime(clock_id, &tp))) {1588 switch (posix.errno(posix.system.clock_gettime(clock_id, &tp))) {
...@@ -1593,8 +1593,8 @@ fn nowPosix(userdata: ?*anyopaque, clock: Io.Clock) Io.Clock.Error!Io.Timestamp...@@ -1593,8 +1593,8 @@ fn nowPosix(userdata: ?*anyopaque, clock: Io.Clock) Io.Clock.Error!Io.Timestamp
1593}1593}
15941594
1595fn nowWindows(userdata: ?*anyopaque, clock: Io.Clock) Io.Clock.Error!Io.Timestamp {1595fn nowWindows(userdata: ?*anyopaque, clock: Io.Clock) Io.Clock.Error!Io.Timestamp {
1596 const pool: *Pool = @ptrCast(@alignCast(userdata));1596 const t: *Threaded = @ptrCast(@alignCast(userdata));
1597 _ = pool;1597 _ = t;
1598 switch (clock) {1598 switch (clock) {
1599 .realtime => {1599 .realtime => {
1600 // RtlGetSystemTimePrecise() has a granularity of 100 nanoseconds1600 // RtlGetSystemTimePrecise() has a granularity of 100 nanoseconds
...@@ -1612,8 +1612,8 @@ fn nowWindows(userdata: ?*anyopaque, clock: Io.Clock) Io.Clock.Error!Io.Timestam...@@ -1612,8 +1612,8 @@ fn nowWindows(userdata: ?*anyopaque, clock: Io.Clock) Io.Clock.Error!Io.Timestam
1612}1612}
16131613
1614fn nowWasi(userdata: ?*anyopaque, clock: Io.Clock) Io.Clock.Error!Io.Timestamp {1614fn nowWasi(userdata: ?*anyopaque, clock: Io.Clock) Io.Clock.Error!Io.Timestamp {
1615 const pool: *Pool = @ptrCast(@alignCast(userdata));1615 const t: *Threaded = @ptrCast(@alignCast(userdata));
1616 _ = pool;1616 _ = t;
1617 var ns: std.os.wasi.timestamp_t = undefined;1617 var ns: std.os.wasi.timestamp_t = undefined;
1618 const err = std.os.wasi.clock_time_get(clockToWasi(clock), 1, &ns);1618 const err = std.os.wasi.clock_time_get(clockToWasi(clock), 1, &ns);
1619 if (err != .SUCCESS) return error.Unexpected;1619 if (err != .SUCCESS) return error.Unexpected;
...@@ -1621,7 +1621,7 @@ fn nowWasi(userdata: ?*anyopaque, clock: Io.Clock) Io.Clock.Error!Io.Timestamp {...@@ -1621,7 +1621,7 @@ fn nowWasi(userdata: ?*anyopaque, clock: Io.Clock) Io.Clock.Error!Io.Timestamp {
1621}1621}
16221622
1623fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {1623fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
1624 const pool: *Pool = @ptrCast(@alignCast(userdata));1624 const t: *Threaded = @ptrCast(@alignCast(userdata));
1625 const clock_id: posix.clockid_t = clockToPosix(switch (timeout) {1625 const clock_id: posix.clockid_t = clockToPosix(switch (timeout) {
1626 .none => .awake,1626 .none => .awake,
1627 .duration => |d| d.clock,1627 .duration => |d| d.clock,
...@@ -1634,7 +1634,7 @@ fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {...@@ -1634,7 +1634,7 @@ fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
1634 };1634 };
1635 var timespec: posix.timespec = timestampToPosix(deadline_nanoseconds);1635 var timespec: posix.timespec = timestampToPosix(deadline_nanoseconds);
1636 while (true) {1636 while (true) {
1637 try pool.checkCancel();1637 try t.checkCancel();
1638 switch (std.os.linux.E.init(std.os.linux.clock_nanosleep(clock_id, .{ .ABSTIME = switch (timeout) {1638 switch (std.os.linux.E.init(std.os.linux.clock_nanosleep(clock_id, .{ .ABSTIME = switch (timeout) {
1639 .none, .duration => false,1639 .none, .duration => false,
1640 .deadline => true,1640 .deadline => true,
...@@ -1648,10 +1648,10 @@ fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {...@@ -1648,10 +1648,10 @@ fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
1648}1648}
16491649
1650fn sleepWindows(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {1650fn sleepWindows(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
1651 const pool: *Pool = @ptrCast(@alignCast(userdata));1651 const t: *Threaded = @ptrCast(@alignCast(userdata));
1652 try pool.checkCancel();1652 try t.checkCancel();
1653 const ms = ms: {1653 const ms = ms: {
1654 const duration_and_clock = (try timeout.toDurationFromNow(pool.io())) orelse1654 const duration_and_clock = (try timeout.toDurationFromNow(t.io())) orelse
1655 break :ms std.math.maxInt(windows.DWORD);1655 break :ms std.math.maxInt(windows.DWORD);
1656 break :ms std.math.lossyCast(windows.DWORD, duration_and_clock.duration.toMilliseconds());1656 break :ms std.math.lossyCast(windows.DWORD, duration_and_clock.duration.toMilliseconds());
1657 };1657 };
...@@ -1659,12 +1659,12 @@ fn sleepWindows(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {...@@ -1659,12 +1659,12 @@ fn sleepWindows(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
1659}1659}
16601660
1661fn sleepWasi(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {1661fn sleepWasi(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
1662 const pool: *Pool = @ptrCast(@alignCast(userdata));1662 const t: *Threaded = @ptrCast(@alignCast(userdata));
1663 try pool.checkCancel();1663 try t.checkCancel();
16641664
1665 const w = std.os.wasi;1665 const w = std.os.wasi;
16661666
1667 const clock: w.subscription_clock_t = if (try timeout.toDurationFromNow(pool.io())) |d| .{1667 const clock: w.subscription_clock_t = if (try timeout.toDurationFromNow(t.io())) |d| .{
1668 .id = clockToWasi(d.clock),1668 .id = clockToWasi(d.clock),
1669 .timeout = std.math.lossyCast(u64, d.duration.nanoseconds),1669 .timeout = std.math.lossyCast(u64, d.duration.nanoseconds),
1670 .precision = 0,1670 .precision = 0,
...@@ -1688,19 +1688,19 @@ fn sleepWasi(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {...@@ -1688,19 +1688,19 @@ fn sleepWasi(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
1688}1688}
16891689
1690fn sleepPosix(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {1690fn sleepPosix(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
1691 const pool: *Pool = @ptrCast(@alignCast(userdata));1691 const t: *Threaded = @ptrCast(@alignCast(userdata));
1692 const sec_type = @typeInfo(posix.timespec).@"struct".fields[0].type;1692 const sec_type = @typeInfo(posix.timespec).@"struct".fields[0].type;
1693 const nsec_type = @typeInfo(posix.timespec).@"struct".fields[1].type;1693 const nsec_type = @typeInfo(posix.timespec).@"struct".fields[1].type;
16941694
1695 var timespec: posix.timespec = t: {1695 var timespec: posix.timespec = t: {
1696 const d = (try timeout.toDurationFromNow(pool.io())) orelse break :t .{1696 const d = (try timeout.toDurationFromNow(t.io())) orelse break :t .{
1697 .sec = std.math.maxInt(sec_type),1697 .sec = std.math.maxInt(sec_type),
1698 .nsec = std.math.maxInt(nsec_type),1698 .nsec = std.math.maxInt(nsec_type),
1699 };1699 };
1700 break :t timestampToPosix(d.duration.nanoseconds);1700 break :t timestampToPosix(d.duration.nanoseconds);
1701 };1701 };
1702 while (true) {1702 while (true) {
1703 try pool.checkCancel();1703 try t.checkCancel();
1704 switch (posix.errno(posix.system.nanosleep(&timespec, &timespec))) {1704 switch (posix.errno(posix.system.nanosleep(&timespec, &timespec))) {
1705 .INTR => continue,1705 .INTR => continue,
1706 else => return, // This prong handles success as well as unexpected errors.1706 else => return, // This prong handles success as well as unexpected errors.
...@@ -1709,8 +1709,8 @@ fn sleepPosix(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {...@@ -1709,8 +1709,8 @@ fn sleepPosix(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
1709}1709}
17101710
1711fn select(userdata: ?*anyopaque, futures: []const *Io.AnyFuture) usize {1711fn select(userdata: ?*anyopaque, futures: []const *Io.AnyFuture) usize {
1712 const pool: *Pool = @ptrCast(@alignCast(userdata));1712 const t: *Threaded = @ptrCast(@alignCast(userdata));
1713 _ = pool;1713 _ = t;
17141714
1715 var reset_event: ResetEvent = .unset;1715 var reset_event: ResetEvent = .unset;
17161716
...@@ -1745,26 +1745,26 @@ fn netListenIpPosix(...@@ -1745,26 +1745,26 @@ fn netListenIpPosix(
1745 address: IpAddress,1745 address: IpAddress,
1746 options: IpAddress.ListenOptions,1746 options: IpAddress.ListenOptions,
1747) IpAddress.ListenError!net.Server {1747) IpAddress.ListenError!net.Server {
1748 const pool: *Pool = @ptrCast(@alignCast(userdata));1748 const t: *Threaded = @ptrCast(@alignCast(userdata));
1749 const family = posixAddressFamily(&address);1749 const family = posixAddressFamily(&address);
1750 const socket_fd = try openSocketPosix(pool, family, .{1750 const socket_fd = try openSocketPosix(t, family, .{
1751 .mode = options.mode,1751 .mode = options.mode,
1752 .protocol = options.protocol,1752 .protocol = options.protocol,
1753 });1753 });
1754 errdefer posix.close(socket_fd);1754 errdefer posix.close(socket_fd);
17551755
1756 if (options.reuse_address) {1756 if (options.reuse_address) {
1757 try setSocketOption(pool, socket_fd, posix.SOL.SOCKET, posix.SO.REUSEADDR, 1);1757 try setSocketOption(t, socket_fd, posix.SOL.SOCKET, posix.SO.REUSEADDR, 1);
1758 if (@hasDecl(posix.SO, "REUSEPORT"))1758 if (@hasDecl(posix.SO, "REUSEPORT"))
1759 try setSocketOption(pool, socket_fd, posix.SOL.SOCKET, posix.SO.REUSEPORT, 1);1759 try setSocketOption(t, socket_fd, posix.SOL.SOCKET, posix.SO.REUSEPORT, 1);
1760 }1760 }
17611761
1762 var storage: PosixAddress = undefined;1762 var storage: PosixAddress = undefined;
1763 var addr_len = addressToPosix(&address, &storage);1763 var addr_len = addressToPosix(&address, &storage);
1764 try posixBind(pool, socket_fd, &storage.any, addr_len);1764 try posixBind(t, socket_fd, &storage.any, addr_len);
17651765
1766 while (true) {1766 while (true) {
1767 try pool.checkCancel();1767 try t.checkCancel();
1768 switch (posix.errno(posix.system.listen(socket_fd, options.kernel_backlog))) {1768 switch (posix.errno(posix.system.listen(socket_fd, options.kernel_backlog))) {
1769 .SUCCESS => break,1769 .SUCCESS => break,
1770 .ADDRINUSE => return error.AddressInUse,1770 .ADDRINUSE => return error.AddressInUse,
...@@ -1773,7 +1773,7 @@ fn netListenIpPosix(...@@ -1773,7 +1773,7 @@ fn netListenIpPosix(
1773 }1773 }
1774 }1774 }
17751775
1776 try posixGetSockName(pool, socket_fd, &storage.any, &addr_len);1776 try posixGetSockName(t, socket_fd, &storage.any, &addr_len);
1777 return .{1777 return .{
1778 .socket = .{1778 .socket = .{
1779 .handle = socket_fd,1779 .handle = socket_fd,
...@@ -1788,8 +1788,8 @@ fn netListenUnix(...@@ -1788,8 +1788,8 @@ fn netListenUnix(
1788 options: net.UnixAddress.ListenOptions,1788 options: net.UnixAddress.ListenOptions,
1789) net.UnixAddress.ListenError!net.Socket.Handle {1789) net.UnixAddress.ListenError!net.Socket.Handle {
1790 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;1790 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
1791 const pool: *Pool = @ptrCast(@alignCast(userdata));1791 const t: *Threaded = @ptrCast(@alignCast(userdata));
1792 const socket_fd = openSocketPosix(pool, posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {1792 const socket_fd = openSocketPosix(t, posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {
1793 error.ProtocolUnsupportedBySystem => return error.AddressFamilyUnsupported,1793 error.ProtocolUnsupportedBySystem => return error.AddressFamilyUnsupported,
1794 error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported,1794 error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported,
1795 error.SocketModeUnsupported => return error.AddressFamilyUnsupported,1795 error.SocketModeUnsupported => return error.AddressFamilyUnsupported,
...@@ -1799,10 +1799,10 @@ fn netListenUnix(...@@ -1799,10 +1799,10 @@ fn netListenUnix(
17991799
1800 var storage: UnixAddress = undefined;1800 var storage: UnixAddress = undefined;
1801 const addr_len = addressUnixToPosix(address, &storage);1801 const addr_len = addressUnixToPosix(address, &storage);
1802 try posixBindUnix(pool, socket_fd, &storage.any, addr_len);1802 try posixBindUnix(t, socket_fd, &storage.any, addr_len);
18031803
1804 while (true) {1804 while (true) {
1805 try pool.checkCancel();1805 try t.checkCancel();
1806 switch (posix.errno(posix.system.listen(socket_fd, options.kernel_backlog))) {1806 switch (posix.errno(posix.system.listen(socket_fd, options.kernel_backlog))) {
1807 .SUCCESS => break,1807 .SUCCESS => break,
1808 .ADDRINUSE => return error.AddressInUse,1808 .ADDRINUSE => return error.AddressInUse,
...@@ -1814,9 +1814,9 @@ fn netListenUnix(...@@ -1814,9 +1814,9 @@ fn netListenUnix(
1814 return socket_fd;1814 return socket_fd;
1815}1815}
18161816
1817fn posixBindUnix(pool: *Pool, fd: posix.socket_t, addr: *const posix.sockaddr, addr_len: posix.socklen_t) !void {1817fn posixBindUnix(t: *Threaded, fd: posix.socket_t, addr: *const posix.sockaddr, addr_len: posix.socklen_t) !void {
1818 while (true) {1818 while (true) {
1819 try pool.checkCancel();1819 try t.checkCancel();
1820 switch (posix.errno(posix.system.bind(fd, addr, addr_len))) {1820 switch (posix.errno(posix.system.bind(fd, addr, addr_len))) {
1821 .SUCCESS => break,1821 .SUCCESS => break,
1822 .INTR => continue,1822 .INTR => continue,
...@@ -1842,9 +1842,9 @@ fn posixBindUnix(pool: *Pool, fd: posix.socket_t, addr: *const posix.sockaddr, a...@@ -1842,9 +1842,9 @@ fn posixBindUnix(pool: *Pool, fd: posix.socket_t, addr: *const posix.sockaddr, a
1842 }1842 }
1843}1843}
18441844
1845fn posixBind(pool: *Pool, socket_fd: posix.socket_t, addr: *const posix.sockaddr, addr_len: posix.socklen_t) !void {1845fn posixBind(t: *Threaded, socket_fd: posix.socket_t, addr: *const posix.sockaddr, addr_len: posix.socklen_t) !void {
1846 while (true) {1846 while (true) {
1847 try pool.checkCancel();1847 try t.checkCancel();
1848 switch (posix.errno(posix.system.bind(socket_fd, addr, addr_len))) {1848 switch (posix.errno(posix.system.bind(socket_fd, addr, addr_len))) {
1849 .SUCCESS => break,1849 .SUCCESS => break,
1850 .INTR => continue,1850 .INTR => continue,
...@@ -1861,9 +1861,9 @@ fn posixBind(pool: *Pool, socket_fd: posix.socket_t, addr: *const posix.sockaddr...@@ -1861,9 +1861,9 @@ fn posixBind(pool: *Pool, socket_fd: posix.socket_t, addr: *const posix.sockaddr
1861 }1861 }
1862}1862}
18631863
1864fn posixConnect(pool: *Pool, socket_fd: posix.socket_t, addr: *const posix.sockaddr, addr_len: posix.socklen_t) !void {1864fn posixConnect(t: *Threaded, socket_fd: posix.socket_t, addr: *const posix.sockaddr, addr_len: posix.socklen_t) !void {
1865 while (true) {1865 while (true) {
1866 try pool.checkCancel();1866 try t.checkCancel();
1867 switch (posix.errno(posix.system.connect(socket_fd, addr, addr_len))) {1867 switch (posix.errno(posix.system.connect(socket_fd, addr, addr_len))) {
1868 .SUCCESS => return,1868 .SUCCESS => return,
1869 .INTR => continue,1869 .INTR => continue,
...@@ -1890,9 +1890,9 @@ fn posixConnect(pool: *Pool, socket_fd: posix.socket_t, addr: *const posix.socka...@@ -1890,9 +1890,9 @@ fn posixConnect(pool: *Pool, socket_fd: posix.socket_t, addr: *const posix.socka
1890 }1890 }
1891}1891}
18921892
1893fn posixConnectUnix(pool: *Pool, fd: posix.socket_t, addr: *const posix.sockaddr, addr_len: posix.socklen_t) !void {1893fn posixConnectUnix(t: *Threaded, fd: posix.socket_t, addr: *const posix.sockaddr, addr_len: posix.socklen_t) !void {
1894 while (true) {1894 while (true) {
1895 try pool.checkCancel();1895 try t.checkCancel();
1896 switch (posix.errno(posix.system.connect(fd, addr, addr_len))) {1896 switch (posix.errno(posix.system.connect(fd, addr, addr_len))) {
1897 .SUCCESS => return,1897 .SUCCESS => return,
1898 .INTR => continue,1898 .INTR => continue,
...@@ -1919,9 +1919,9 @@ fn posixConnectUnix(pool: *Pool, fd: posix.socket_t, addr: *const posix.sockaddr...@@ -1919,9 +1919,9 @@ fn posixConnectUnix(pool: *Pool, fd: posix.socket_t, addr: *const posix.sockaddr
1919 }1919 }
1920}1920}
19211921
1922fn posixGetSockName(pool: *Pool, socket_fd: posix.fd_t, addr: *posix.sockaddr, addr_len: *posix.socklen_t) !void {1922fn posixGetSockName(t: *Threaded, socket_fd: posix.fd_t, addr: *posix.sockaddr, addr_len: *posix.socklen_t) !void {
1923 while (true) {1923 while (true) {
1924 try pool.checkCancel();1924 try t.checkCancel();
1925 switch (posix.errno(posix.system.getsockname(socket_fd, addr, addr_len))) {1925 switch (posix.errno(posix.system.getsockname(socket_fd, addr, addr_len))) {
1926 .SUCCESS => break,1926 .SUCCESS => break,
1927 .INTR => continue,1927 .INTR => continue,
...@@ -1935,10 +1935,10 @@ fn posixGetSockName(pool: *Pool, socket_fd: posix.fd_t, addr: *posix.sockaddr, a...@@ -1935,10 +1935,10 @@ fn posixGetSockName(pool: *Pool, socket_fd: posix.fd_t, addr: *posix.sockaddr, a
1935 }1935 }
1936}1936}
19371937
1938fn setSocketOption(pool: *Pool, fd: posix.fd_t, level: i32, opt_name: u32, option: u32) !void {1938fn setSocketOption(t: *Threaded, fd: posix.fd_t, level: i32, opt_name: u32, option: u32) !void {
1939 const o: []const u8 = @ptrCast(&option);1939 const o: []const u8 = @ptrCast(&option);
1940 while (true) {1940 while (true) {
1941 try pool.checkCancel();1941 try t.checkCancel();
1942 switch (posix.errno(posix.system.setsockopt(fd, level, opt_name, o.ptr, @intCast(o.len)))) {1942 switch (posix.errno(posix.system.setsockopt(fd, level, opt_name, o.ptr, @intCast(o.len)))) {
1943 .SUCCESS => return,1943 .SUCCESS => return,
1944 .INTR => continue,1944 .INTR => continue,
...@@ -1957,17 +1957,17 @@ fn netConnectIpPosix(...@@ -1957,17 +1957,17 @@ fn netConnectIpPosix(
1957 options: IpAddress.ConnectOptions,1957 options: IpAddress.ConnectOptions,
1958) IpAddress.ConnectError!net.Stream {1958) IpAddress.ConnectError!net.Stream {
1959 if (options.timeout != .none) @panic("TODO");1959 if (options.timeout != .none) @panic("TODO");
1960 const pool: *Pool = @ptrCast(@alignCast(userdata));1960 const t: *Threaded = @ptrCast(@alignCast(userdata));
1961 const family = posixAddressFamily(address);1961 const family = posixAddressFamily(address);
1962 const socket_fd = try openSocketPosix(pool, family, .{1962 const socket_fd = try openSocketPosix(t, family, .{
1963 .mode = options.mode,1963 .mode = options.mode,
1964 .protocol = options.protocol,1964 .protocol = options.protocol,
1965 });1965 });
1966 errdefer posix.close(socket_fd);1966 errdefer posix.close(socket_fd);
1967 var storage: PosixAddress = undefined;1967 var storage: PosixAddress = undefined;
1968 var addr_len = addressToPosix(address, &storage);1968 var addr_len = addressToPosix(address, &storage);
1969 try posixConnect(pool, socket_fd, &storage.any, addr_len);1969 try posixConnect(t, socket_fd, &storage.any, addr_len);
1970 try posixGetSockName(pool, socket_fd, &storage.any, &addr_len);1970 try posixGetSockName(t, socket_fd, &storage.any, &addr_len);
1971 return .{ .socket = .{1971 return .{ .socket = .{
1972 .handle = socket_fd,1972 .handle = socket_fd,
1973 .address = addressFromPosix(&storage),1973 .address = addressFromPosix(&storage),
...@@ -1979,12 +1979,12 @@ fn netConnectUnix(...@@ -1979,12 +1979,12 @@ fn netConnectUnix(
1979 address: *const net.UnixAddress,1979 address: *const net.UnixAddress,
1980) net.UnixAddress.ConnectError!net.Socket.Handle {1980) net.UnixAddress.ConnectError!net.Socket.Handle {
1981 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;1981 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
1982 const pool: *Pool = @ptrCast(@alignCast(userdata));1982 const t: *Threaded = @ptrCast(@alignCast(userdata));
1983 const socket_fd = try openSocketPosix(pool, posix.AF.UNIX, .{ .mode = .stream });1983 const socket_fd = try openSocketPosix(t, posix.AF.UNIX, .{ .mode = .stream });
1984 errdefer posix.close(socket_fd);1984 errdefer posix.close(socket_fd);
1985 var storage: UnixAddress = undefined;1985 var storage: UnixAddress = undefined;
1986 const addr_len = addressUnixToPosix(address, &storage);1986 const addr_len = addressUnixToPosix(address, &storage);
1987 try posixConnectUnix(pool, socket_fd, &storage.any, addr_len);1987 try posixConnectUnix(t, socket_fd, &storage.any, addr_len);
1988 return socket_fd;1988 return socket_fd;
1989}1989}
19901990
...@@ -1993,25 +1993,25 @@ fn netBindIpPosix(...@@ -1993,25 +1993,25 @@ fn netBindIpPosix(
1993 address: *const IpAddress,1993 address: *const IpAddress,
1994 options: IpAddress.BindOptions,1994 options: IpAddress.BindOptions,
1995) IpAddress.BindError!net.Socket {1995) IpAddress.BindError!net.Socket {
1996 const pool: *Pool = @ptrCast(@alignCast(userdata));1996 const t: *Threaded = @ptrCast(@alignCast(userdata));
1997 const family = posixAddressFamily(address);1997 const family = posixAddressFamily(address);
1998 const socket_fd = try openSocketPosix(pool, family, options);1998 const socket_fd = try openSocketPosix(t, family, options);
1999 errdefer posix.close(socket_fd);1999 errdefer posix.close(socket_fd);
2000 var storage: PosixAddress = undefined;2000 var storage: PosixAddress = undefined;
2001 var addr_len = addressToPosix(address, &storage);2001 var addr_len = addressToPosix(address, &storage);
2002 try posixBind(pool, socket_fd, &storage.any, addr_len);2002 try posixBind(t, socket_fd, &storage.any, addr_len);
2003 try posixGetSockName(pool, socket_fd, &storage.any, &addr_len);2003 try posixGetSockName(t, socket_fd, &storage.any, &addr_len);
2004 return .{2004 return .{
2005 .handle = socket_fd,2005 .handle = socket_fd,
2006 .address = addressFromPosix(&storage),2006 .address = addressFromPosix(&storage),
2007 };2007 };
2008}2008}
20092009
2010fn openSocketPosix(pool: *Pool, family: posix.sa_family_t, options: IpAddress.BindOptions) !posix.socket_t {2010fn openSocketPosix(t: *Threaded, family: posix.sa_family_t, options: IpAddress.BindOptions) !posix.socket_t {
2011 const mode = posixSocketMode(options.mode);2011 const mode = posixSocketMode(options.mode);
2012 const protocol = posixProtocol(options.protocol);2012 const protocol = posixProtocol(options.protocol);
2013 const socket_fd = while (true) {2013 const socket_fd = while (true) {
2014 try pool.checkCancel();2014 try t.checkCancel();
2015 const flags: u32 = mode | if (socket_flags_unsupported) 0 else posix.SOCK.CLOEXEC;2015 const flags: u32 = mode | if (socket_flags_unsupported) 0 else posix.SOCK.CLOEXEC;
2016 const socket_rc = posix.system.socket(family, flags, protocol);2016 const socket_rc = posix.system.socket(family, flags, protocol);
2017 switch (posix.errno(socket_rc)) {2017 switch (posix.errno(socket_rc)) {
...@@ -2019,7 +2019,7 @@ fn openSocketPosix(pool: *Pool, family: posix.sa_family_t, options: IpAddress.Bi...@@ -2019,7 +2019,7 @@ fn openSocketPosix(pool: *Pool, family: posix.sa_family_t, options: IpAddress.Bi
2019 const fd: posix.fd_t = @intCast(socket_rc);2019 const fd: posix.fd_t = @intCast(socket_rc);
2020 errdefer posix.close(fd);2020 errdefer posix.close(fd);
2021 if (socket_flags_unsupported) while (true) {2021 if (socket_flags_unsupported) while (true) {
2022 try pool.checkCancel();2022 try t.checkCancel();
2023 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) {2023 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) {
2024 .SUCCESS => break,2024 .SUCCESS => break,
2025 .INTR => continue,2025 .INTR => continue,
...@@ -2044,7 +2044,7 @@ fn openSocketPosix(pool: *Pool, family: posix.sa_family_t, options: IpAddress.Bi...@@ -2044,7 +2044,7 @@ fn openSocketPosix(pool: *Pool, family: posix.sa_family_t, options: IpAddress.Bi
20442044
2045 if (options.ip6_only) {2045 if (options.ip6_only) {
2046 if (posix.IPV6 == void) return error.OptionUnsupported;2046 if (posix.IPV6 == void) return error.OptionUnsupported;
2047 try setSocketOption(pool, socket_fd, posix.IPPROTO.IPV6, posix.IPV6.V6ONLY, 0);2047 try setSocketOption(t, socket_fd, posix.IPPROTO.IPV6, posix.IPV6.V6ONLY, 0);
2048 }2048 }
20492049
2050 return socket_fd;2050 return socket_fd;
...@@ -2054,11 +2054,11 @@ const socket_flags_unsupported = builtin.os.tag.isDarwin() or native_os == .haik...@@ -2054,11 +2054,11 @@ const socket_flags_unsupported = builtin.os.tag.isDarwin() or native_os == .haik
2054const have_accept4 = !socket_flags_unsupported;2054const have_accept4 = !socket_flags_unsupported;
20552055
2056fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Server.AcceptError!net.Stream {2056fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Server.AcceptError!net.Stream {
2057 const pool: *Pool = @ptrCast(@alignCast(userdata));2057 const t: *Threaded = @ptrCast(@alignCast(userdata));
2058 var storage: PosixAddress = undefined;2058 var storage: PosixAddress = undefined;
2059 var addr_len: posix.socklen_t = @sizeOf(PosixAddress);2059 var addr_len: posix.socklen_t = @sizeOf(PosixAddress);
2060 const fd = while (true) {2060 const fd = while (true) {
2061 try pool.checkCancel();2061 try t.checkCancel();
2062 const rc = if (have_accept4)2062 const rc = if (have_accept4)
2063 posix.system.accept4(listen_fd, &storage.any, &addr_len, posix.SOCK.CLOEXEC)2063 posix.system.accept4(listen_fd, &storage.any, &addr_len, posix.SOCK.CLOEXEC)
2064 else2064 else
...@@ -2068,7 +2068,7 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve...@@ -2068,7 +2068,7 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve
2068 const fd: posix.fd_t = @intCast(rc);2068 const fd: posix.fd_t = @intCast(rc);
2069 errdefer posix.close(fd);2069 errdefer posix.close(fd);
2070 if (!have_accept4) while (true) {2070 if (!have_accept4) while (true) {
2071 try pool.checkCancel();2071 try t.checkCancel();
2072 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) {2072 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) {
2073 .SUCCESS => break,2073 .SUCCESS => break,
2074 .INTR => continue,2074 .INTR => continue,
...@@ -2101,7 +2101,7 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve...@@ -2101,7 +2101,7 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve
2101}2101}
21022102
2103fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {2103fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
2104 const pool: *Pool = @ptrCast(@alignCast(userdata));2104 const t: *Threaded = @ptrCast(@alignCast(userdata));
21052105
2106 var iovecs_buffer: [max_iovecs_len]posix.iovec = undefined;2106 var iovecs_buffer: [max_iovecs_len]posix.iovec = undefined;
2107 var i: usize = 0;2107 var i: usize = 0;
...@@ -2116,7 +2116,7 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net....@@ -2116,7 +2116,7 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
2116 assert(dest[0].len > 0);2116 assert(dest[0].len > 0);
21172117
2118 if (native_os == .wasi and !builtin.link_libc) while (true) {2118 if (native_os == .wasi and !builtin.link_libc) while (true) {
2119 try pool.checkCancel();2119 try t.checkCancel();
2120 var n: usize = undefined;2120 var n: usize = undefined;
2121 switch (std.os.wasi.fd_read(fd, dest.ptr, dest.len, &n)) {2121 switch (std.os.wasi.fd_read(fd, dest.ptr, dest.len, &n)) {
2122 .SUCCESS => return n,2122 .SUCCESS => return n,
...@@ -2137,7 +2137,7 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net....@@ -2137,7 +2137,7 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
2137 };2137 };
21382138
2139 while (true) {2139 while (true) {
2140 try pool.checkCancel();2140 try t.checkCancel();
2141 const rc = posix.system.readv(fd, dest.ptr, @intCast(dest.len));2141 const rc = posix.system.readv(fd, dest.ptr, @intCast(dest.len));
2142 switch (posix.errno(rc)) {2142 switch (posix.errno(rc)) {
2143 .SUCCESS => return @intCast(rc),2143 .SUCCESS => return @intCast(rc),
...@@ -2167,7 +2167,7 @@ fn netSend(...@@ -2167,7 +2167,7 @@ fn netSend(
2167 messages: []net.OutgoingMessage,2167 messages: []net.OutgoingMessage,
2168 flags: net.SendFlags,2168 flags: net.SendFlags,
2169) struct { ?net.Socket.SendError, usize } {2169) struct { ?net.Socket.SendError, usize } {
2170 const pool: *Pool = @ptrCast(@alignCast(userdata));2170 const t: *Threaded = @ptrCast(@alignCast(userdata));
21712171
2172 const posix_flags: u32 =2172 const posix_flags: u32 =
2173 @as(u32, if (@hasDecl(posix.MSG, "CONFIRM") and flags.confirm) posix.MSG.CONFIRM else 0) |2173 @as(u32, if (@hasDecl(posix.MSG, "CONFIRM") and flags.confirm) posix.MSG.CONFIRM else 0) |
...@@ -2180,17 +2180,17 @@ fn netSend(...@@ -2180,17 +2180,17 @@ fn netSend(
2180 var i: usize = 0;2180 var i: usize = 0;
2181 while (messages.len - i != 0) {2181 while (messages.len - i != 0) {
2182 if (have_sendmmsg) {2182 if (have_sendmmsg) {
2183 i += netSendMany(pool, handle, messages[i..], posix_flags) catch |err| return .{ err, i };2183 i += netSendMany(t, handle, messages[i..], posix_flags) catch |err| return .{ err, i };
2184 continue;2184 continue;
2185 }2185 }
2186 netSendOne(pool, handle, &messages[i], posix_flags) catch |err| return .{ err, i };2186 netSendOne(t, handle, &messages[i], posix_flags) catch |err| return .{ err, i };
2187 i += 1;2187 i += 1;
2188 }2188 }
2189 return .{ null, i };2189 return .{ null, i };
2190}2190}
21912191
2192fn netSendOne(2192fn netSendOne(
2193 pool: *Pool,2193 t: *Threaded,
2194 handle: net.Socket.Handle,2194 handle: net.Socket.Handle,
2195 message: *net.OutgoingMessage,2195 message: *net.OutgoingMessage,
2196 flags: u32,2196 flags: u32,
...@@ -2207,7 +2207,7 @@ fn netSendOne(...@@ -2207,7 +2207,7 @@ fn netSendOne(
2207 .flags = 0,2207 .flags = 0,
2208 };2208 };
2209 while (true) {2209 while (true) {
2210 try pool.checkCancel();2210 try t.checkCancel();
2211 const rc = posix.system.sendmsg(handle, msg, flags);2211 const rc = posix.system.sendmsg(handle, msg, flags);
2212 if (is_windows) {2212 if (is_windows) {
2213 if (rc == windows.ws2_32.SOCKET_ERROR) {2213 if (rc == windows.ws2_32.SOCKET_ERROR) {
...@@ -2274,7 +2274,7 @@ fn netSendOne(...@@ -2274,7 +2274,7 @@ fn netSendOne(
2274}2274}
22752275
2276fn netSendMany(2276fn netSendMany(
2277 pool: *Pool,2277 t: *Threaded,
2278 handle: net.Socket.Handle,2278 handle: net.Socket.Handle,
2279 messages: []net.OutgoingMessage,2279 messages: []net.OutgoingMessage,
2280 flags: u32,2280 flags: u32,
...@@ -2305,7 +2305,7 @@ fn netSendMany(...@@ -2305,7 +2305,7 @@ fn netSendMany(
2305 }2305 }
23062306
2307 while (true) {2307 while (true) {
2308 try pool.checkCancel();2308 try t.checkCancel();
2309 const rc = posix.system.sendmmsg(handle, clamped_msgs.ptr, @intCast(clamped_msgs.len), flags);2309 const rc = posix.system.sendmmsg(handle, clamped_msgs.ptr, @intCast(clamped_msgs.len), flags);
2310 switch (posix.errno(rc)) {2310 switch (posix.errno(rc)) {
2311 .SUCCESS => {2311 .SUCCESS => {
...@@ -2348,7 +2348,7 @@ fn netReceive(...@@ -2348,7 +2348,7 @@ fn netReceive(
2348 flags: net.ReceiveFlags,2348 flags: net.ReceiveFlags,
2349 timeout: Io.Timeout,2349 timeout: Io.Timeout,
2350) struct { ?net.Socket.ReceiveTimeoutError, usize } {2350) struct { ?net.Socket.ReceiveTimeoutError, usize } {
2351 const pool: *Pool = @ptrCast(@alignCast(userdata));2351 const t: *Threaded = @ptrCast(@alignCast(userdata));
23522352
2353 // recvmmsg is useless, here's why:2353 // recvmmsg is useless, here's why:
2354 // * [timeout bug](https://bugzilla.kernel.org/show_bug.cgi?id=75371)2354 // * [timeout bug](https://bugzilla.kernel.org/show_bug.cgi?id=75371)
...@@ -2375,10 +2375,10 @@ fn netReceive(...@@ -2375,10 +2375,10 @@ fn netReceive(
2375 var message_i: usize = 0;2375 var message_i: usize = 0;
2376 var data_i: usize = 0;2376 var data_i: usize = 0;
23772377
2378 const deadline = timeout.toDeadline(pool.io()) catch |err| return .{ err, message_i };2378 const deadline = timeout.toDeadline(t.io()) catch |err| return .{ err, message_i };
23792379
2380 recv: while (true) {2380 recv: while (true) {
2381 pool.checkCancel() catch |err| return .{ err, message_i };2381 t.checkCancel() catch |err| return .{ err, message_i };
23822382
2383 if (message_buffer.len - message_i == 0) return .{ null, message_i };2383 if (message_buffer.len - message_i == 0) return .{ null, message_i };
2384 const message = &message_buffer[message_i];2384 const message = &message_buffer[message_i];
...@@ -2416,12 +2416,12 @@ fn netReceive(...@@ -2416,12 +2416,12 @@ fn netReceive(
2416 continue;2416 continue;
2417 },2417 },
2418 .AGAIN => while (true) {2418 .AGAIN => while (true) {
2419 pool.checkCancel() catch |err| return .{ err, message_i };2419 t.checkCancel() catch |err| return .{ err, message_i };
2420 if (message_i != 0) return .{ null, message_i };2420 if (message_i != 0) return .{ null, message_i };
24212421
2422 const max_poll_ms = std.math.maxInt(u31);2422 const max_poll_ms = std.math.maxInt(u31);
2423 const timeout_ms: u31 = if (deadline) |d| t: {2423 const timeout_ms: u31 = if (deadline) |d| t: {
2424 const duration = d.durationFromNow(pool.io()) catch |err| return .{ err, message_i };2424 const duration = d.durationFromNow(t.io()) catch |err| return .{ err, message_i };
2425 if (duration.raw.nanoseconds <= 0) return .{ error.Timeout, message_i };2425 if (duration.raw.nanoseconds <= 0) return .{ error.Timeout, message_i };
2426 break :t @intCast(@min(max_poll_ms, duration.raw.toMilliseconds()));2426 break :t @intCast(@min(max_poll_ms, duration.raw.toMilliseconds()));
2427 } else max_poll_ms;2427 } else max_poll_ms;
...@@ -2473,8 +2473,8 @@ fn netWritePosix(...@@ -2473,8 +2473,8 @@ fn netWritePosix(
2473 data: []const []const u8,2473 data: []const []const u8,
2474 splat: usize,2474 splat: usize,
2475) net.Stream.Writer.Error!usize {2475) net.Stream.Writer.Error!usize {
2476 const pool: *Pool = @ptrCast(@alignCast(userdata));2476 const t: *Threaded = @ptrCast(@alignCast(userdata));
2477 try pool.checkCancel();2477 try t.checkCancel();
24782478
2479 var iovecs: [max_iovecs_len]posix.iovec_const = undefined;2479 var iovecs: [max_iovecs_len]posix.iovec_const = undefined;
2480 var msg: posix.msghdr_const = .{2480 var msg: posix.msghdr_const = .{
...@@ -2527,8 +2527,8 @@ fn addBuf(v: []posix.iovec_const, i: *@FieldType(posix.msghdr_const, "iovlen"),...@@ -2527,8 +2527,8 @@ fn addBuf(v: []posix.iovec_const, i: *@FieldType(posix.msghdr_const, "iovlen"),
2527}2527}
25282528
2529fn netClose(userdata: ?*anyopaque, handle: net.Socket.Handle) void {2529fn netClose(userdata: ?*anyopaque, handle: net.Socket.Handle) void {
2530 const pool: *Pool = @ptrCast(@alignCast(userdata));2530 const t: *Threaded = @ptrCast(@alignCast(userdata));
2531 _ = pool;2531 _ = t;
2532 switch (native_os) {2532 switch (native_os) {
2533 .windows => windows.closesocket(handle) catch recoverableOsBugDetected(),2533 .windows => windows.closesocket(handle) catch recoverableOsBugDetected(),
2534 else => posix.close(handle),2534 else => posix.close(handle),
...@@ -2539,10 +2539,10 @@ fn netInterfaceNameResolve(...@@ -2539,10 +2539,10 @@ fn netInterfaceNameResolve(
2539 userdata: ?*anyopaque,2539 userdata: ?*anyopaque,
2540 name: *const net.Interface.Name,2540 name: *const net.Interface.Name,
2541) net.Interface.Name.ResolveError!net.Interface {2541) net.Interface.Name.ResolveError!net.Interface {
2542 const pool: *Pool = @ptrCast(@alignCast(userdata));2542 const t: *Threaded = @ptrCast(@alignCast(userdata));
25432543
2544 if (native_os == .linux) {2544 if (native_os == .linux) {
2545 const sock_fd = openSocketPosix(pool, posix.AF.UNIX, .{ .mode = .dgram }) catch |err| switch (err) {2545 const sock_fd = openSocketPosix(t, posix.AF.UNIX, .{ .mode = .dgram }) catch |err| switch (err) {
2546 error.ProcessFdQuotaExceeded => return error.SystemResources,2546 error.ProcessFdQuotaExceeded => return error.SystemResources,
2547 error.SystemFdQuotaExceeded => return error.SystemResources,2547 error.SystemFdQuotaExceeded => return error.SystemResources,
2548 error.AddressFamilyUnsupported => return error.Unexpected,2548 error.AddressFamilyUnsupported => return error.Unexpected,
...@@ -2559,7 +2559,7 @@ fn netInterfaceNameResolve(...@@ -2559,7 +2559,7 @@ fn netInterfaceNameResolve(
2559 };2559 };
25602560
2561 while (true) {2561 while (true) {
2562 try pool.checkCancel();2562 try t.checkCancel();
2563 switch (posix.errno(posix.system.ioctl(sock_fd, posix.SIOCGIFINDEX, @intFromPtr(&ifr)))) {2563 switch (posix.errno(posix.system.ioctl(sock_fd, posix.SIOCGIFINDEX, @intFromPtr(&ifr)))) {
2564 .SUCCESS => return .{ .index = @bitCast(ifr.ifru.ivalue) },2564 .SUCCESS => return .{ .index = @bitCast(ifr.ifru.ivalue) },
2565 .INTR => continue,2565 .INTR => continue,
...@@ -2576,14 +2576,14 @@ fn netInterfaceNameResolve(...@@ -2576,14 +2576,14 @@ fn netInterfaceNameResolve(
2576 }2576 }
25772577
2578 if (native_os == .windows) {2578 if (native_os == .windows) {
2579 try pool.checkCancel();2579 try t.checkCancel();
2580 const index = std.os.windows.ws2_32.if_nametoindex(&name.bytes);2580 const index = std.os.windows.ws2_32.if_nametoindex(&name.bytes);
2581 if (index == 0) return error.InterfaceNotFound;2581 if (index == 0) return error.InterfaceNotFound;
2582 return .{ .index = index };2582 return .{ .index = index };
2583 }2583 }
25842584
2585 if (builtin.link_libc) {2585 if (builtin.link_libc) {
2586 try pool.checkCancel();2586 try t.checkCancel();
2587 const index = std.c.if_nametoindex(&name.bytes);2587 const index = std.c.if_nametoindex(&name.bytes);
2588 if (index == 0) return error.InterfaceNotFound;2588 if (index == 0) return error.InterfaceNotFound;
2589 return .{ .index = @bitCast(index) };2589 return .{ .index = @bitCast(index) };
...@@ -2593,8 +2593,8 @@ fn netInterfaceNameResolve(...@@ -2593,8 +2593,8 @@ fn netInterfaceNameResolve(
2593}2593}
25942594
2595fn netInterfaceName(userdata: ?*anyopaque, interface: net.Interface) net.Interface.NameError!net.Interface.Name {2595fn netInterfaceName(userdata: ?*anyopaque, interface: net.Interface) net.Interface.NameError!net.Interface.Name {
2596 const pool: *Pool = @ptrCast(@alignCast(userdata));2596 const t: *Threaded = @ptrCast(@alignCast(userdata));
2597 try pool.checkCancel();2597 try t.checkCancel();
25982598
2599 if (native_os == .linux) {2599 if (native_os == .linux) {
2600 _ = interface;2600 _ = interface;
...@@ -2618,18 +2618,18 @@ fn netLookup(...@@ -2618,18 +2618,18 @@ fn netLookup(
2618 resolved: *Io.Queue(HostName.LookupResult),2618 resolved: *Io.Queue(HostName.LookupResult),
2619 options: HostName.LookupOptions,2619 options: HostName.LookupOptions,
2620) void {2620) void {
2621 const pool: *Pool = @ptrCast(@alignCast(userdata));2621 const t: *Threaded = @ptrCast(@alignCast(userdata));
2622 const pool_io = pool.io();2622 const t_io = t.io();
2623 resolved.putOneUncancelable(pool_io, .{ .end = netLookupFallible(pool, host_name, resolved, options) });2623 resolved.putOneUncancelable(t_io, .{ .end = netLookupFallible(t, host_name, resolved, options) });
2624}2624}
26252625
2626fn netLookupFallible(2626fn netLookupFallible(
2627 pool: *Pool,2627 t: *Threaded,
2628 host_name: HostName,2628 host_name: HostName,
2629 resolved: *Io.Queue(HostName.LookupResult),2629 resolved: *Io.Queue(HostName.LookupResult),
2630 options: HostName.LookupOptions,2630 options: HostName.LookupOptions,
2631) !void {2631) !void {
2632 const pool_io = pool.io();2632 const t_io = t.io();
2633 const name = host_name.bytes;2633 const name = host_name.bytes;
2634 assert(name.len <= HostName.max_len);2634 assert(name.len <= HostName.max_len);
26352635
...@@ -2648,7 +2648,7 @@ fn netLookupFallible(...@@ -2648,7 +2648,7 @@ fn netLookupFallible(
2648 if (native_os == .linux) {2648 if (native_os == .linux) {
2649 if (options.family != .ip4) {2649 if (options.family != .ip4) {
2650 if (IpAddress.parseIp6(name, options.port)) |addr| {2650 if (IpAddress.parseIp6(name, options.port)) |addr| {
2651 try resolved.putAll(pool_io, &.{2651 try resolved.putAll(t_io, &.{
2652 .{ .address = addr },2652 .{ .address = addr },
2653 .{ .canonical_name = copyCanon(options.canonical_name_buffer, name) },2653 .{ .canonical_name = copyCanon(options.canonical_name_buffer, name) },
2654 });2654 });
...@@ -2658,7 +2658,7 @@ fn netLookupFallible(...@@ -2658,7 +2658,7 @@ fn netLookupFallible(
26582658
2659 if (options.family != .ip6) {2659 if (options.family != .ip6) {
2660 if (IpAddress.parseIp4(name, options.port)) |addr| {2660 if (IpAddress.parseIp4(name, options.port)) |addr| {
2661 try resolved.putAll(pool_io, &.{2661 try resolved.putAll(t_io, &.{
2662 .{ .address = addr },2662 .{ .address = addr },
2663 .{ .canonical_name = copyCanon(options.canonical_name_buffer, name) },2663 .{ .canonical_name = copyCanon(options.canonical_name_buffer, name) },
2664 });2664 });
...@@ -2666,7 +2666,7 @@ fn netLookupFallible(...@@ -2666,7 +2666,7 @@ fn netLookupFallible(
2666 } else |_| {}2666 } else |_| {}
2667 }2667 }
26682668
2669 lookupHosts(pool, host_name, resolved, options) catch |err| switch (err) {2669 lookupHosts(t, host_name, resolved, options) catch |err| switch (err) {
2670 error.UnknownHostName => {},2670 error.UnknownHostName => {},
2671 else => |e| return e,2671 else => |e| return e,
2672 };2672 };
...@@ -2697,11 +2697,11 @@ fn netLookupFallible(...@@ -2697,11 +2697,11 @@ fn netLookupFallible(
2697 canon_name_dest.* = canon_name.*;2697 canon_name_dest.* = canon_name.*;
2698 results_buffer[results_index] = .{ .canonical_name = .{ .bytes = canon_name_dest } };2698 results_buffer[results_index] = .{ .canonical_name = .{ .bytes = canon_name_dest } };
2699 results_index += 1;2699 results_index += 1;
2700 try resolved.putAll(pool_io, results_buffer[0..results_index]);2700 try resolved.putAll(t_io, results_buffer[0..results_index]);
2701 return;2701 return;
2702 }2702 }
27032703
2704 return lookupDnsSearch(pool, host_name, resolved, options);2704 return lookupDnsSearch(t, host_name, resolved, options);
2705 }2705 }
27062706
2707 if (native_os == .openbsd) {2707 if (native_os == .openbsd) {
...@@ -2953,13 +2953,13 @@ fn pathToPosix(file_path: []const u8, buffer: *[posix.PATH_MAX]u8) Io.Dir.PathNa...@@ -2953,13 +2953,13 @@ fn pathToPosix(file_path: []const u8, buffer: *[posix.PATH_MAX]u8) Io.Dir.PathNa
2953}2953}
29542954
2955fn lookupDnsSearch(2955fn lookupDnsSearch(
2956 pool: *Pool,2956 t: *Threaded,
2957 host_name: HostName,2957 host_name: HostName,
2958 resolved: *Io.Queue(HostName.LookupResult),2958 resolved: *Io.Queue(HostName.LookupResult),
2959 options: HostName.LookupOptions,2959 options: HostName.LookupOptions,
2960) HostName.LookupError!void {2960) HostName.LookupError!void {
2961 const pool_io = pool.io();2961 const t_io = t.io();
2962 const rc = HostName.ResolvConf.init(pool_io) catch return error.ResolvConfParseFailed;2962 const rc = HostName.ResolvConf.init(t_io) catch return error.ResolvConfParseFailed;
29632963
2964 // Count dots, suppress search when >=ndots or name ends in2964 // Count dots, suppress search when >=ndots or name ends in
2965 // a dot, which is an explicit request for global scope.2965 // a dot, which is an explicit request for global scope.
...@@ -2983,7 +2983,7 @@ fn lookupDnsSearch(...@@ -2983,7 +2983,7 @@ fn lookupDnsSearch(
2983 while (it.next()) |token| {2983 while (it.next()) |token| {
2984 @memcpy(options.canonical_name_buffer[canon_name.len + 1 ..][0..token.len], token);2984 @memcpy(options.canonical_name_buffer[canon_name.len + 1 ..][0..token.len], token);
2985 const lookup_canon_name = options.canonical_name_buffer[0 .. canon_name.len + 1 + token.len];2985 const lookup_canon_name = options.canonical_name_buffer[0 .. canon_name.len + 1 + token.len];
2986 if (lookupDns(pool, lookup_canon_name, &rc, resolved, options)) |result| {2986 if (lookupDns(t, lookup_canon_name, &rc, resolved, options)) |result| {
2987 return result;2987 return result;
2988 } else |err| switch (err) {2988 } else |err| switch (err) {
2989 error.UnknownHostName => continue,2989 error.UnknownHostName => continue,
...@@ -2992,17 +2992,17 @@ fn lookupDnsSearch(...@@ -2992,17 +2992,17 @@ fn lookupDnsSearch(
2992 }2992 }
29932993
2994 const lookup_canon_name = options.canonical_name_buffer[0..canon_name.len];2994 const lookup_canon_name = options.canonical_name_buffer[0..canon_name.len];
2995 return lookupDns(pool, lookup_canon_name, &rc, resolved, options);2995 return lookupDns(t, lookup_canon_name, &rc, resolved, options);
2996}2996}
29972997
2998fn lookupDns(2998fn lookupDns(
2999 pool: *Pool,2999 t: *Threaded,
3000 lookup_canon_name: []const u8,3000 lookup_canon_name: []const u8,
3001 rc: *const HostName.ResolvConf,3001 rc: *const HostName.ResolvConf,
3002 resolved: *Io.Queue(HostName.LookupResult),3002 resolved: *Io.Queue(HostName.LookupResult),
3003 options: HostName.LookupOptions,3003 options: HostName.LookupOptions,
3004) HostName.LookupError!void {3004) HostName.LookupError!void {
3005 const pool_io = pool.io();3005 const t_io = t.io();
3006 const family_records: [2]struct { af: IpAddress.Family, rr: u8 } = .{3006 const family_records: [2]struct { af: IpAddress.Family, rr: u8 } = .{
3007 .{ .af = .ip6, .rr = std.posix.RR.A },3007 .{ .af = .ip6, .rr = std.posix.RR.A },
3008 .{ .af = .ip4, .rr = std.posix.RR.AAAA },3008 .{ .af = .ip4, .rr = std.posix.RR.AAAA },
...@@ -3032,7 +3032,7 @@ fn lookupDns(...@@ -3032,7 +3032,7 @@ fn lookupDns(
3032 var socket = s: {3032 var socket = s: {
3033 if (any_ip6) ip6: {3033 if (any_ip6) ip6: {
3034 const ip6_addr: IpAddress = .{ .ip6 = .unspecified(0) };3034 const ip6_addr: IpAddress = .{ .ip6 = .unspecified(0) };
3035 const socket = ip6_addr.bind(pool_io, .{ .ip6_only = true, .mode = .dgram }) catch |err| switch (err) {3035 const socket = ip6_addr.bind(t_io, .{ .ip6_only = true, .mode = .dgram }) catch |err| switch (err) {
3036 error.AddressFamilyUnsupported => break :ip6,3036 error.AddressFamilyUnsupported => break :ip6,
3037 else => |e| return e,3037 else => |e| return e,
3038 };3038 };
...@@ -3040,10 +3040,10 @@ fn lookupDns(...@@ -3040,10 +3040,10 @@ fn lookupDns(
3040 }3040 }
3041 any_ip6 = false;3041 any_ip6 = false;
3042 const ip4_addr: IpAddress = .{ .ip4 = .unspecified(0) };3042 const ip4_addr: IpAddress = .{ .ip4 = .unspecified(0) };
3043 const socket = try ip4_addr.bind(pool_io, .{ .mode = .dgram });3043 const socket = try ip4_addr.bind(t_io, .{ .mode = .dgram });
3044 break :s socket;3044 break :s socket;
3045 };3045 };
3046 defer socket.close(pool_io);3046 defer socket.close(t_io);
30473047
3048 const mapped_nameservers = if (any_ip6) ip4_mapped[0..rc.nameservers_len] else rc.nameservers();3048 const mapped_nameservers = if (any_ip6) ip4_mapped[0..rc.nameservers_len] else rc.nameservers();
3049 const queries = queries_buffer[0..nq];3049 const queries = queries_buffer[0..nq];
...@@ -3054,13 +3054,13 @@ fn lookupDns(...@@ -3054,13 +3054,13 @@ fn lookupDns(
3054 // boot clock is chosen because time the computer is suspended should count3054 // boot clock is chosen because time the computer is suspended should count
3055 // against time spent waiting for external messages to arrive.3055 // against time spent waiting for external messages to arrive.
3056 const clock: Io.Clock = .boot;3056 const clock: Io.Clock = .boot;
3057 var now_ts = try clock.now(pool_io);3057 var now_ts = try clock.now(t_io);
3058 const final_ts = now_ts.addDuration(.fromSeconds(rc.timeout_seconds));3058 const final_ts = now_ts.addDuration(.fromSeconds(rc.timeout_seconds));
3059 const attempt_duration: Io.Duration = .{3059 const attempt_duration: Io.Duration = .{
3060 .nanoseconds = std.time.ns_per_s * @as(usize, rc.timeout_seconds) / rc.attempts,3060 .nanoseconds = std.time.ns_per_s * @as(usize, rc.timeout_seconds) / rc.attempts,
3061 };3061 };
30623062
3063 send: while (now_ts.nanoseconds < final_ts.nanoseconds) : (now_ts = try clock.now(pool_io)) {3063 send: while (now_ts.nanoseconds < final_ts.nanoseconds) : (now_ts = try clock.now(t_io)) {
3064 const max_messages = queries_buffer.len * HostName.ResolvConf.max_nameservers;3064 const max_messages = queries_buffer.len * HostName.ResolvConf.max_nameservers;
3065 {3065 {
3066 var message_buffer: [max_messages]Io.net.OutgoingMessage = undefined;3066 var message_buffer: [max_messages]Io.net.OutgoingMessage = undefined;
...@@ -3076,7 +3076,7 @@ fn lookupDns(...@@ -3076,7 +3076,7 @@ fn lookupDns(
3076 message_i += 1;3076 message_i += 1;
3077 }3077 }
3078 }3078 }
3079 _ = netSend(pool, socket.handle, message_buffer[0..message_i], .{});3079 _ = netSend(t, socket.handle, message_buffer[0..message_i], .{});
3080 }3080 }
30813081
3082 const timeout: Io.Timeout = .{ .deadline = .{3082 const timeout: Io.Timeout = .{ .deadline = .{
...@@ -3087,7 +3087,7 @@ fn lookupDns(...@@ -3087,7 +3087,7 @@ fn lookupDns(
3087 while (true) {3087 while (true) {
3088 var message_buffer: [max_messages]Io.net.IncomingMessage = undefined;3088 var message_buffer: [max_messages]Io.net.IncomingMessage = undefined;
3089 const buf = answer_buffer[answer_buffer_i..];3089 const buf = answer_buffer[answer_buffer_i..];
3090 const recv_err, const recv_n = socket.receiveManyTimeout(pool_io, &message_buffer, buf, .{}, timeout);3090 const recv_err, const recv_n = socket.receiveManyTimeout(t_io, &message_buffer, buf, .{}, timeout);
3091 for (message_buffer[0..recv_n]) |*received_message| {3091 for (message_buffer[0..recv_n]) |*received_message| {
3092 const reply = received_message.data;3092 const reply = received_message.data;
3093 // Ignore non-identifiable packets.3093 // Ignore non-identifiable packets.
...@@ -3124,7 +3124,7 @@ fn lookupDns(...@@ -3124,7 +3124,7 @@ fn lookupDns(
3124 .data_ptr = query.ptr,3124 .data_ptr = query.ptr,
3125 .data_len = query.len,3125 .data_len = query.len,
3126 };3126 };
3127 _ = netSend(pool, socket.handle, (&retry_message)[0..1], .{});3127 _ = netSend(t, socket.handle, (&retry_message)[0..1], .{});
3128 continue;3128 continue;
3129 },3129 },
3130 else => continue,3130 else => continue,
...@@ -3155,7 +3155,7 @@ fn lookupDns(...@@ -3155,7 +3155,7 @@ fn lookupDns(
3155 std.posix.RR.A => {3155 std.posix.RR.A => {
3156 const data = record.packet[record.data_off..][0..record.data_len];3156 const data = record.packet[record.data_off..][0..record.data_len];
3157 if (data.len != 4) return error.InvalidDnsARecord;3157 if (data.len != 4) return error.InvalidDnsARecord;
3158 try resolved.putOne(pool_io, .{ .address = .{ .ip4 = .{3158 try resolved.putOne(t_io, .{ .address = .{ .ip4 = .{
3159 .bytes = data[0..4].*,3159 .bytes = data[0..4].*,
3160 .port = options.port,3160 .port = options.port,
3161 } } });3161 } } });
...@@ -3164,7 +3164,7 @@ fn lookupDns(...@@ -3164,7 +3164,7 @@ fn lookupDns(
3164 std.posix.RR.AAAA => {3164 std.posix.RR.AAAA => {
3165 const data = record.packet[record.data_off..][0..record.data_len];3165 const data = record.packet[record.data_off..][0..record.data_len];
3166 if (data.len != 16) return error.InvalidDnsAAAARecord;3166 if (data.len != 16) return error.InvalidDnsAAAARecord;
3167 try resolved.putOne(pool_io, .{ .address = .{ .ip6 = .{3167 try resolved.putOne(t_io, .{ .address = .{ .ip6 = .{
3168 .bytes = data[0..16].*,3168 .bytes = data[0..16].*,
3169 .port = options.port,3169 .port = options.port,
3170 } } });3170 } } });
...@@ -3178,18 +3178,18 @@ fn lookupDns(...@@ -3178,18 +3178,18 @@ fn lookupDns(
3178 };3178 };
3179 }3179 }
31803180
3181 try resolved.putOne(pool_io, .{ .canonical_name = canonical_name orelse .{ .bytes = lookup_canon_name } });3181 try resolved.putOne(t_io, .{ .canonical_name = canonical_name orelse .{ .bytes = lookup_canon_name } });
3182 if (addresses_len == 0) return error.NameServerFailure;3182 if (addresses_len == 0) return error.NameServerFailure;
3183}3183}
31843184
3185fn lookupHosts(3185fn lookupHosts(
3186 pool: *Pool,3186 t: *Threaded,
3187 host_name: HostName,3187 host_name: HostName,
3188 resolved: *Io.Queue(HostName.LookupResult),3188 resolved: *Io.Queue(HostName.LookupResult),
3189 options: HostName.LookupOptions,3189 options: HostName.LookupOptions,
3190) !void {3190) !void {
3191 const pool_io = pool.io();3191 const t_io = t.io();
3192 const file = Io.File.openAbsolute(pool_io, "/etc/hosts", .{}) catch |err| switch (err) {3192 const file = Io.File.openAbsolute(t_io, "/etc/hosts", .{}) catch |err| switch (err) {
3193 error.FileNotFound,3193 error.FileNotFound,
3194 error.NotDir,3194 error.NotDir,
3195 error.AccessDenied,3195 error.AccessDenied,
...@@ -3202,11 +3202,11 @@ fn lookupHosts(...@@ -3202,11 +3202,11 @@ fn lookupHosts(
3202 return error.DetectingNetworkConfigurationFailed;3202 return error.DetectingNetworkConfigurationFailed;
3203 },3203 },
3204 };3204 };
3205 defer file.close(pool_io);3205 defer file.close(t_io);
32063206
3207 var line_buf: [512]u8 = undefined;3207 var line_buf: [512]u8 = undefined;
3208 var file_reader = file.reader(pool_io, &line_buf);3208 var file_reader = file.reader(t_io, &line_buf);
3209 return lookupHostsReader(pool, host_name, resolved, options, &file_reader.interface) catch |err| switch (err) {3209 return lookupHostsReader(t, host_name, resolved, options, &file_reader.interface) catch |err| switch (err) {
3210 error.ReadFailed => switch (file_reader.err.?) {3210 error.ReadFailed => switch (file_reader.err.?) {
3211 error.Canceled => |e| return e,3211 error.Canceled => |e| return e,
3212 else => {3212 else => {
...@@ -3220,13 +3220,13 @@ fn lookupHosts(...@@ -3220,13 +3220,13 @@ fn lookupHosts(
3220}3220}
32213221
3222fn lookupHostsReader(3222fn lookupHostsReader(
3223 pool: *Pool,3223 t: *Threaded,
3224 host_name: HostName,3224 host_name: HostName,
3225 resolved: *Io.Queue(HostName.LookupResult),3225 resolved: *Io.Queue(HostName.LookupResult),
3226 options: HostName.LookupOptions,3226 options: HostName.LookupOptions,
3227 reader: *Io.Reader,3227 reader: *Io.Reader,
3228) error{ ReadFailed, Canceled, UnknownHostName }!void {3228) error{ ReadFailed, Canceled, UnknownHostName }!void {
3229 const pool_io = pool.io();3229 const t_io = t.io();
3230 var addresses_len: usize = 0;3230 var addresses_len: usize = 0;
3231 var canonical_name: ?HostName = null;3231 var canonical_name: ?HostName = null;
3232 while (true) {3232 while (true) {
...@@ -3268,19 +3268,19 @@ fn lookupHostsReader(...@@ -3268,19 +3268,19 @@ fn lookupHostsReader(
32683268
3269 if (options.family != .ip6) {3269 if (options.family != .ip6) {
3270 if (IpAddress.parseIp4(ip_text, options.port)) |addr| {3270 if (IpAddress.parseIp4(ip_text, options.port)) |addr| {
3271 try resolved.putOne(pool_io, .{ .address = addr });3271 try resolved.putOne(t_io, .{ .address = addr });
3272 addresses_len += 1;3272 addresses_len += 1;
3273 } else |_| {}3273 } else |_| {}
3274 }3274 }
3275 if (options.family != .ip4) {3275 if (options.family != .ip4) {
3276 if (IpAddress.parseIp6(ip_text, options.port)) |addr| {3276 if (IpAddress.parseIp6(ip_text, options.port)) |addr| {
3277 try resolved.putOne(pool_io, .{ .address = addr });3277 try resolved.putOne(t_io, .{ .address = addr });
3278 addresses_len += 1;3278 addresses_len += 1;
3279 } else |_| {}3279 } else |_| {}
3280 }3280 }
3281 }3281 }
32823282
3283 if (canonical_name) |canon_name| try resolved.putOne(pool_io, .{ .canonical_name = canon_name });3283 if (canonical_name) |canon_name| try resolved.putOne(t_io, .{ .canonical_name = canon_name });
3284 if (addresses_len == 0) return error.UnknownHostName;3284 if (addresses_len == 0) return error.UnknownHostName;
3285}3285}
32863286