| ... | ... | @@ -177,7 +177,6 @@ pub fn io(t: *Threaded) Io { |
| 177 | 177 | |
| 178 | 178 | .groupAsync = groupAsync, |
| 179 | 179 | .groupWait = groupWait, |
| 180 | | .groupWaitUncancelable = groupWaitUncancelable, |
| 181 | 180 | .groupCancel = groupCancel, |
| 182 | 181 | |
| 183 | 182 | .mutexLock = mutexLock, |
| ... | ... | @@ -274,7 +273,6 @@ pub fn ioBasic(t: *Threaded) Io { |
| 274 | 273 | |
| 275 | 274 | .groupAsync = groupAsync, |
| 276 | 275 | .groupWait = groupWait, |
| 277 | | .groupWaitUncancelable = groupWaitUncancelable, |
| 278 | 276 | .groupCancel = groupCancel, |
| 279 | 277 | |
| 280 | 278 | .mutexLock = mutexLock, |
| ... | ... | @@ -579,7 +577,9 @@ const GroupClosure = struct { |
| 579 | 577 | assert(cancel_tid == .canceling); |
| 580 | 578 | } |
| 581 | 579 | |
| 582 | | syncFinish(group_state, reset_event); |
| 580 | const prev_state = group_state.fetchSub(sync_one_pending, .acq_rel); |
| 581 | assert((prev_state / sync_one_pending) > 0); |
| 582 | if (prev_state == (sync_one_pending | sync_is_waiting)) reset_event.set(); |
| 583 | 583 | } |
| 584 | 584 | |
| 585 | 585 | fn free(gc: *GroupClosure, gpa: Allocator) void { |
| ... | ... | @@ -602,29 +602,6 @@ const GroupClosure = struct { |
| 602 | 602 | |
| 603 | 603 | const sync_is_waiting: usize = 1 << 0; |
| 604 | 604 | const sync_one_pending: usize = 1 << 1; |
| 605 | | |
| 606 | | fn syncStart(state: *std.atomic.Value(usize)) void { |
| 607 | | const prev_state = state.fetchAdd(sync_one_pending, .monotonic); |
| 608 | | assert((prev_state / sync_one_pending) < (std.math.maxInt(usize) / sync_one_pending)); |
| 609 | | } |
| 610 | | |
| 611 | | fn syncFinish(state: *std.atomic.Value(usize), event: *ResetEvent) void { |
| 612 | | const prev_state = state.fetchSub(sync_one_pending, .acq_rel); |
| 613 | | assert((prev_state / sync_one_pending) > 0); |
| 614 | | if (prev_state == (sync_one_pending | sync_is_waiting)) event.set(); |
| 615 | | } |
| 616 | | |
| 617 | | fn syncWait(t: *Threaded, state: *std.atomic.Value(usize), event: *ResetEvent) Io.Cancelable!void { |
| 618 | | const prev_state = state.fetchAdd(sync_is_waiting, .acquire); |
| 619 | | assert(prev_state & sync_is_waiting == 0); |
| 620 | | if ((prev_state / sync_one_pending) > 0) try event.wait(t); |
| 621 | | } |
| 622 | | |
| 623 | | fn syncWaitUncancelable(state: *std.atomic.Value(usize), event: *ResetEvent) void { |
| 624 | | const prev_state = state.fetchAdd(sync_is_waiting, .acquire); |
| 625 | | assert(prev_state & sync_is_waiting == 0); |
| 626 | | if ((prev_state / sync_one_pending) > 0) event.waitUncancelable(); |
| 627 | | } |
| 628 | 605 | }; |
| 629 | 606 | |
| 630 | 607 | fn groupAsync( |
| ... | ... | @@ -686,32 +663,14 @@ fn groupAsync( |
| 686 | 663 | // This needs to be done before unlocking the mutex to avoid a race with |
| 687 | 664 | // the associated task finishing. |
| 688 | 665 | const group_state: *std.atomic.Value(usize) = @ptrCast(&group.state); |
| 689 | | GroupClosure.syncStart(group_state); |
| 666 | const prev_state = group_state.fetchAdd(GroupClosure.sync_one_pending, .monotonic); |
| 667 | assert((prev_state / GroupClosure.sync_one_pending) < (std.math.maxInt(usize) / GroupClosure.sync_one_pending)); |
| 690 | 668 | |
| 691 | 669 | t.mutex.unlock(); |
| 692 | 670 | t.cond.signal(); |
| 693 | 671 | } |
| 694 | 672 | |
| 695 | | fn groupWait(userdata: ?*anyopaque, group: *Io.Group, token: *anyopaque) Io.Cancelable!void { |
| 696 | | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 697 | | const gpa = t.allocator; |
| 698 | | |
| 699 | | if (builtin.single_threaded) return; |
| 700 | | |
| 701 | | const group_state: *std.atomic.Value(usize) = @ptrCast(&group.state); |
| 702 | | const reset_event: *ResetEvent = @ptrCast(&group.context); |
| 703 | | try GroupClosure.syncWait(t, group_state, reset_event); |
| 704 | | |
| 705 | | var node: *std.SinglyLinkedList.Node = @ptrCast(@alignCast(token)); |
| 706 | | while (true) { |
| 707 | | const gc: *GroupClosure = @fieldParentPtr("node", node); |
| 708 | | const node_next = node.next; |
| 709 | | gc.free(gpa); |
| 710 | | node = node_next orelse break; |
| 711 | | } |
| 712 | | } |
| 713 | | |
| 714 | | fn groupWaitUncancelable(userdata: ?*anyopaque, group: *Io.Group, token: *anyopaque) void { |
| 673 | fn groupWait(userdata: ?*anyopaque, group: *Io.Group, token: *anyopaque) void { |
| 715 | 674 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 716 | 675 | const gpa = t.allocator; |
| 717 | 676 | |
| ... | ... | @@ -719,7 +678,19 @@ fn groupWaitUncancelable(userdata: ?*anyopaque, group: *Io.Group, token: *anyopa |
| 719 | 678 | |
| 720 | 679 | const group_state: *std.atomic.Value(usize) = @ptrCast(&group.state); |
| 721 | 680 | const reset_event: *ResetEvent = @ptrCast(&group.context); |
| 722 | | GroupClosure.syncWaitUncancelable(group_state, reset_event); |
| 681 | const prev_state = group_state.fetchAdd(GroupClosure.sync_is_waiting, .acquire); |
| 682 | assert(prev_state & GroupClosure.sync_is_waiting == 0); |
| 683 | if ((prev_state / GroupClosure.sync_one_pending) > 0) reset_event.wait(t) catch |err| switch (err) { |
| 684 | error.Canceled => { |
| 685 | var node: *std.SinglyLinkedList.Node = @ptrCast(@alignCast(token)); |
| 686 | while (true) { |
| 687 | const gc: *GroupClosure = @fieldParentPtr("node", node); |
| 688 | gc.closure.requestCancel(); |
| 689 | node = node.next orelse break; |
| 690 | } |
| 691 | reset_event.waitUncancelable(); |
| 692 | }, |
| 693 | }; |
| 723 | 694 | |
| 724 | 695 | var node: *std.SinglyLinkedList.Node = @ptrCast(@alignCast(token)); |
| 725 | 696 | while (true) { |
| ... | ... | @@ -747,7 +718,9 @@ fn groupCancel(userdata: ?*anyopaque, group: *Io.Group, token: *anyopaque) void |
| 747 | 718 | |
| 748 | 719 | const group_state: *std.atomic.Value(usize) = @ptrCast(&group.state); |
| 749 | 720 | const reset_event: *ResetEvent = @ptrCast(&group.context); |
| 750 | | GroupClosure.syncWaitUncancelable(group_state, reset_event); |
| 721 | const prev_state = group_state.fetchAdd(GroupClosure.sync_is_waiting, .acquire); |
| 722 | assert(prev_state & GroupClosure.sync_is_waiting == 0); |
| 723 | if ((prev_state / GroupClosure.sync_one_pending) > 0) reset_event.waitUncancelable(); |
| 751 | 724 | |
| 752 | 725 | { |
| 753 | 726 | var node: *std.SinglyLinkedList.Node = @ptrCast(@alignCast(token)); |
| ... | ... | @@ -1549,7 +1522,7 @@ fn dirAccessPosix( |
| 1549 | 1522 | .FAULT => |err| return errnoBug(err), |
| 1550 | 1523 | .IO => return error.InputOutput, |
| 1551 | 1524 | .NOMEM => return error.SystemResources, |
| 1552 | | .ILSEQ => return error.BadPathName, // TODO move to wasi |
| 1525 | .ILSEQ => return error.BadPathName, |
| 1553 | 1526 | else => |err| return posix.unexpectedErrno(err), |
| 1554 | 1527 | } |
| 1555 | 1528 | } |