| ... | ... | @@ -655,7 +655,19 @@ pub const IO_Uring = struct { |
| 655 | 655 | } |
| 656 | 656 | |
| 657 | 657 | /// Queues (but does not submit) an SQE to perform an async zerocopy `send(2)`. |
| 658 | | /// Returns a pointer to the SQE. |
| 658 | /// |
| 659 | /// This operation will most likely produce two CQEs. The flags field of the |
| 660 | /// first cqe may likely contain IORING_CQE_F_MORE, which means that there will |
| 661 | /// be a second cqe with the user_data field set to the same value. The user |
| 662 | /// must not modify the data buffer until the notification is posted. The first |
| 663 | /// cqe follows the usual rules and so its res field will contain the number of |
| 664 | /// bytes sent or a negative error code. The notification's res field will be |
| 665 | /// set to zero and the flags field will contain IORING_CQE_F_NOTIF. The two |
| 666 | /// step model is needed because the kernel may hold on to buffers for a long |
| 667 | /// time, e.g. waiting for a TCP ACK. Notifications responsible for controlling |
| 668 | /// the lifetime of the buffers. Even errored requests may generate a |
| 669 | /// notification. |
| 670 | /// |
| 659 | 671 | /// Available since 6.0 |
| 660 | 672 | pub fn send_zc( |
| 661 | 673 | self: *IO_Uring, |
| ... | ... | @@ -3805,8 +3817,7 @@ test "accept/connect/send_zc/recv" { |
| 3805 | 3817 | const send = try ring.send_zc(0xeeeeeeee, socket_test_harness.client, buffer_send[0..], 0, 0); |
| 3806 | 3818 | send.flags |= linux.IOSQE_IO_LINK; |
| 3807 | 3819 | _ = try ring.recv(0xffffffff, socket_test_harness.server, .{ .buffer = buffer_recv[0..] }, 0); |
| 3808 | | const submitted = try ring.submit(); |
| 3809 | | if (submitted != 2) return error.SkipZigTest; // on kernel 5.8 (without zc support) |
| 3820 | try testing.expectEqual(@as(u32, 2), try ring.submit()); |
| 3810 | 3821 | |
| 3811 | 3822 | // First completion of zero-copy send. |
| 3812 | 3823 | // IORING_CQE_F_MORE, means that there |
| ... | ... | @@ -4112,16 +4123,5 @@ test "openat_direct/close_direct" { |
| 4112 | 4123 | /// For use in tests. Returns SkipZigTest is kernel version is less than required. |
| 4113 | 4124 | fn skipKernelLessThan(required: std.SemanticVersion) !void { |
| 4114 | 4125 | if (builtin.os.tag != .linux) return error.SkipZigTest; |
| 4115 | | |
| 4116 | | var uts: linux.utsname = undefined; |
| 4117 | | const res = linux.uname(&uts); |
| 4118 | | switch (linux.getErrno(res)) { |
| 4119 | | .SUCCESS => {}, |
| 4120 | | else => |errno| return os.unexpectedErrno(errno), |
| 4121 | | } |
| 4122 | | |
| 4123 | | const release = mem.sliceTo(&uts.release, 0); |
| 4124 | | var current = try std.SemanticVersion.parse(release); |
| 4125 | | current.pre = null; // don't check pre field |
| 4126 | | if (required.order(current) == .gt) return error.SkipZigTest; |
| 4126 | if (required.order(builtin.os.version_range.linux.range.max) == .gt) return error.SkipZigTest; |
| 4127 | 4127 | } |