| ... | @@ -917,17 +917,19 @@ pub const TypeErasedQueue = struct { | ... | @@ -917,17 +917,19 @@ pub const TypeErasedQueue = struct { |
| 917 | put_index: usize, | 917 | put_index: usize, |
| 918 | get_index: usize, | 918 | get_index: usize, |
| 919 | | 919 | |
| 920 | putters: std.DoublyLinkedList(PutNode), | 920 | putters: std.DoublyLinkedList, |
| 921 | getters: std.DoublyLinkedList(GetNode), | 921 | getters: std.DoublyLinkedList, |
| 922 | | 922 | |
| 923 | const PutNode = struct { | 923 | const Put = struct { |
| 924 | remaining: []const u8, | 924 | remaining: []const u8, |
| 925 | condition: Condition, | 925 | condition: Condition, |
| | 926 | node: std.DoublyLinkedList.Node, |
| 926 | }; | 927 | }; |
| 927 | | 928 | |
| 928 | const GetNode = struct { | 929 | const Get = struct { |
| 929 | remaining: []u8, | 930 | remaining: []u8, |
| 930 | condition: Condition, | 931 | condition: Condition, |
| | 932 | node: std.DoublyLinkedList.Node, |
| 931 | }; | 933 | }; |
| 932 | | 934 | |
| 933 | pub fn init(buffer: []u8) TypeErasedQueue { | 935 | pub fn init(buffer: []u8) TypeErasedQueue { |
| ... | @@ -952,16 +954,16 @@ pub const TypeErasedQueue = struct { | ... | @@ -952,16 +954,16 @@ pub const TypeErasedQueue = struct { |
| 952 | | 954 | |
| 953 | var remaining = elements; | 955 | var remaining = elements; |
| 954 | while (true) { | 956 | while (true) { |
| 955 | const getter = q.getters.popFirst() orelse break; | 957 | const getter: *Get = @fieldParentPtr("node", q.getters.popFirst() orelse break); |
| 956 | const copy_len = @min(getter.data.remaining.len, remaining.len); | 958 | const copy_len = @min(getter.remaining.len, remaining.len); |
| 957 | @memcpy(getter.data.remaining[0..copy_len], remaining[0..copy_len]); | 959 | @memcpy(getter.remaining[0..copy_len], remaining[0..copy_len]); |
| 958 | remaining = remaining[copy_len..]; | 960 | remaining = remaining[copy_len..]; |
| 959 | getter.data.remaining = getter.data.remaining[copy_len..]; | 961 | getter.remaining = getter.remaining[copy_len..]; |
| 960 | if (getter.data.remaining.len == 0) { | 962 | if (getter.remaining.len == 0) { |
| 961 | getter.data.condition.signal(io); | 963 | getter.condition.signal(io); |
| 962 | continue; | 964 | continue; |
| 963 | } | 965 | } |
| 964 | q.getters.prepend(getter); | 966 | q.getters.prepend(&getter.node); |
| 965 | assert(remaining.len == 0); | 967 | assert(remaining.len == 0); |
| 966 | return elements.len; | 968 | return elements.len; |
| 967 | } | 969 | } |
| ... | @@ -987,12 +989,10 @@ pub const TypeErasedQueue = struct { | ... | @@ -987,12 +989,10 @@ pub const TypeErasedQueue = struct { |
| 987 | const total_filled = elements.len - remaining.len; | 989 | const total_filled = elements.len - remaining.len; |
| 988 | if (total_filled >= min) return total_filled; | 990 | if (total_filled >= min) return total_filled; |
| 989 | | 991 | |
| 990 | var node: std.DoublyLinkedList(PutNode).Node = .{ | 992 | var pending: Put = .{ .remaining = remaining, .condition = .{}, .node = .{} }; |
| 991 | .data = .{ .remaining = remaining, .condition = .{} }, | 993 | q.putters.append(&pending.node); |
| 992 | }; | 994 | try pending.condition.wait(io, &q.mutex); |
| 993 | q.putters.append(&node); | 995 | remaining = pending.remaining; |
| 994 | try node.data.condition.wait(io, &q.mutex); | | |
| 995 | remaining = node.data.remaining; | | |
| 996 | } | 996 | } |
| 997 | } | 997 | } |
| 998 | | 998 | |
| ... | @@ -1035,16 +1035,16 @@ pub const TypeErasedQueue = struct { | ... | @@ -1035,16 +1035,16 @@ pub const TypeErasedQueue = struct { |
| 1035 | } | 1035 | } |
| 1036 | // Copy directly from putters into buffer. | 1036 | // Copy directly from putters into buffer. |
| 1037 | while (remaining.len > 0) { | 1037 | while (remaining.len > 0) { |
| 1038 | const putter = q.putters.popFirst() orelse break; | 1038 | const putter: *Put = @fieldParentPtr("node", q.putters.popFirst() orelse break); |
| 1039 | const copy_len = @min(putter.data.remaining.len, remaining.len); | 1039 | const copy_len = @min(putter.remaining.len, remaining.len); |
| 1040 | @memcpy(remaining[0..copy_len], putter.data.remaining[0..copy_len]); | 1040 | @memcpy(remaining[0..copy_len], putter.remaining[0..copy_len]); |
| 1041 | putter.data.remaining = putter.data.remaining[copy_len..]; | 1041 | putter.remaining = putter.remaining[copy_len..]; |
| 1042 | remaining = remaining[copy_len..]; | 1042 | remaining = remaining[copy_len..]; |
| 1043 | if (putter.data.remaining.len == 0) { | 1043 | if (putter.remaining.len == 0) { |
| 1044 | putter.data.condition.signal(io); | 1044 | putter.condition.signal(io); |
| 1045 | } else { | 1045 | } else { |
| 1046 | assert(remaining.len == 0); | 1046 | assert(remaining.len == 0); |
| 1047 | q.putters.prepend(putter); | 1047 | q.putters.prepend(&putter.node); |
| 1048 | return fillRingBufferFromPutters(q, io, buffer.len); | 1048 | return fillRingBufferFromPutters(q, io, buffer.len); |
| 1049 | } | 1049 | } |
| 1050 | } | 1050 | } |
| ... | @@ -1052,12 +1052,10 @@ pub const TypeErasedQueue = struct { | ... | @@ -1052,12 +1052,10 @@ pub const TypeErasedQueue = struct { |
| 1052 | const total_filled = buffer.len - remaining.len; | 1052 | const total_filled = buffer.len - remaining.len; |
| 1053 | if (total_filled >= min) return total_filled; | 1053 | if (total_filled >= min) return total_filled; |
| 1054 | | 1054 | |
| 1055 | var node: std.DoublyLinkedList(GetNode).Node = .{ | 1055 | var pending: Get = .{ .remaining = remaining, .condition = .{}, .node = .{} }; |
| 1056 | .data = .{ .remaining = remaining, .condition = .{} }, | 1056 | q.getters.append(&pending.node); |
| 1057 | }; | 1057 | try pending.condition.wait(io, &q.mutex); |
| 1058 | q.getters.append(&node); | 1058 | remaining = pending.remaining; |
| 1059 | try node.data.condition.wait(io, &q.mutex); | | |
| 1060 | remaining = node.data.remaining; | | |
| 1061 | } | 1059 | } |
| 1062 | } | 1060 | } |
| 1063 | | 1061 | |
| ... | @@ -1067,26 +1065,26 @@ pub const TypeErasedQueue = struct { | ... | @@ -1067,26 +1065,26 @@ pub const TypeErasedQueue = struct { |
| 1067 | /// buffers been fully copied. | 1065 | /// buffers been fully copied. |
| 1068 | fn fillRingBufferFromPutters(q: *TypeErasedQueue, io: Io, len: usize) usize { | 1066 | fn fillRingBufferFromPutters(q: *TypeErasedQueue, io: Io, len: usize) usize { |
| 1069 | while (true) { | 1067 | while (true) { |
| 1070 | const putter = q.putters.popFirst() orelse return len; | 1068 | const putter: *Put = @fieldParentPtr("node", q.putters.popFirst() orelse return len); |
| 1071 | const available = q.buffer[q.put_index..]; | 1069 | const available = q.buffer[q.put_index..]; |
| 1072 | const copy_len = @min(available.len, putter.data.remaining.len); | 1070 | const copy_len = @min(available.len, putter.remaining.len); |
| 1073 | @memcpy(available[0..copy_len], putter.data.remaining[0..copy_len]); | 1071 | @memcpy(available[0..copy_len], putter.remaining[0..copy_len]); |
| 1074 | putter.data.remaining = putter.data.remaining[copy_len..]; | 1072 | putter.remaining = putter.remaining[copy_len..]; |
| 1075 | q.put_index += copy_len; | 1073 | q.put_index += copy_len; |
| 1076 | if (putter.data.remaining.len == 0) { | 1074 | if (putter.remaining.len == 0) { |
| 1077 | putter.data.condition.signal(io); | 1075 | putter.condition.signal(io); |
| 1078 | continue; | 1076 | continue; |
| 1079 | } | 1077 | } |
| 1080 | const second_available = q.buffer[0..q.get_index]; | 1078 | const second_available = q.buffer[0..q.get_index]; |
| 1081 | const second_copy_len = @min(second_available.len, putter.data.remaining.len); | 1079 | const second_copy_len = @min(second_available.len, putter.remaining.len); |
| 1082 | @memcpy(second_available[0..second_copy_len], putter.data.remaining[0..second_copy_len]); | 1080 | @memcpy(second_available[0..second_copy_len], putter.remaining[0..second_copy_len]); |
| 1083 | putter.data.remaining = putter.data.remaining[copy_len..]; | 1081 | putter.remaining = putter.remaining[copy_len..]; |
| 1084 | q.put_index = copy_len; | 1082 | q.put_index = copy_len; |
| 1085 | if (putter.data.remaining.len == 0) { | 1083 | if (putter.remaining.len == 0) { |
| 1086 | putter.data.condition.signal(io); | 1084 | putter.condition.signal(io); |
| 1087 | continue; | 1085 | continue; |
| 1088 | } | 1086 | } |
| 1089 | q.putters.prepend(putter); | 1087 | q.putters.prepend(&putter.node); |
| 1090 | return len; | 1088 | return len; |
| 1091 | } | 1089 | } |
| 1092 | } | 1090 | } |