| ... | @@ -857,6 +857,41 @@ pub const IO_Uring = struct { | ... | @@ -857,6 +857,41 @@ pub const IO_Uring = struct { |
| 857 | return sqe; | 857 | return sqe; |
| 858 | } | 858 | } |
| 859 | | 859 | |
| | 860 | /// Queues (but does not submit) an SQE to provide a group of buffers used for commands that read/receive data. |
| | 861 | /// Returns a pointer to the SQE. |
| | 862 | /// |
| | 863 | /// Provided buffers can be used in `read`, `recv` or `recvmsg` commands via .buffer_selection. |
| | 864 | /// |
| | 865 | /// The kernel expects a contiguous block of memory of size (buffers_count * buffer_size). |
| | 866 | pub fn provide_buffers( |
| | 867 | self: *IO_Uring, |
| | 868 | user_data: u64, |
| | 869 | buffers: [*]u8, |
| | 870 | buffers_count: usize, |
| | 871 | buffer_size: usize, |
| | 872 | group_id: usize, |
| | 873 | buffer_id: usize, |
| | 874 | ) !*io_uring_sqe { |
| | 875 | const sqe = try self.get_sqe(); |
| | 876 | io_uring_prep_provide_buffers(sqe, buffers, buffers_count, buffer_size, group_id, buffer_id); |
| | 877 | sqe.user_data = user_data; |
| | 878 | return sqe; |
| | 879 | } |
| | 880 | |
| | 881 | /// Queues (but does not submit) an SQE to remove a group of provided buffers. |
| | 882 | /// Returns a pointer to the SQE. |
| | 883 | pub fn remove_buffers( |
| | 884 | self: *IO_Uring, |
| | 885 | user_data: u64, |
| | 886 | buffers_count: usize, |
| | 887 | group_id: usize, |
| | 888 | ) !*io_uring_sqe { |
| | 889 | const sqe = try self.get_sqe(); |
| | 890 | io_uring_prep_remove_buffers(sqe, buffers_count, group_id); |
| | 891 | sqe.user_data = user_data; |
| | 892 | return sqe; |
| | 893 | } |
| | 894 | |
| 860 | /// Registers an array of file descriptors. | 895 | /// Registers an array of file descriptors. |
| 861 | /// Every time a file descriptor is put in an SQE and submitted to the kernel, the kernel must | 896 | /// Every time a file descriptor is put in an SQE and submitted to the kernel, the kernel must |
| 862 | /// retrieve a reference to the file, and once I/O has completed the file reference must be | 897 | /// retrieve a reference to the file, and once I/O has completed the file reference must be |
| ... | @@ -1508,6 +1543,28 @@ pub fn io_uring_prep_linkat( | ... | @@ -1508,6 +1543,28 @@ pub fn io_uring_prep_linkat( |
| 1508 | sqe.rw_flags = flags; | 1543 | sqe.rw_flags = flags; |
| 1509 | } | 1544 | } |
| 1510 | | 1545 | |
| | 1546 | pub fn io_uring_prep_provide_buffers( |
| | 1547 | sqe: *io_uring_sqe, |
| | 1548 | buffers: [*]u8, |
| | 1549 | num: usize, |
| | 1550 | buffer_len: usize, |
| | 1551 | group_id: usize, |
| | 1552 | buffer_id: usize, |
| | 1553 | ) void { |
| | 1554 | const ptr = @ptrToInt(buffers); |
| | 1555 | io_uring_prep_rw(.PROVIDE_BUFFERS, sqe, @intCast(i32, num), ptr, buffer_len, buffer_id); |
| | 1556 | sqe.buf_index = @intCast(u16, group_id); |
| | 1557 | } |
| | 1558 | |
| | 1559 | pub fn io_uring_prep_remove_buffers( |
| | 1560 | sqe: *io_uring_sqe, |
| | 1561 | num: usize, |
| | 1562 | group_id: usize, |
| | 1563 | ) void { |
| | 1564 | io_uring_prep_rw(.REMOVE_BUFFERS, sqe, @intCast(i32, num), 0, 0, 0); |
| | 1565 | sqe.buf_index = @intCast(u16, group_id); |
| | 1566 | } |
| | 1567 | |
| 1511 | test "structs/offsets/entries" { | 1568 | test "structs/offsets/entries" { |
| 1512 | if (builtin.os.tag != .linux) return error.SkipZigTest; | 1569 | if (builtin.os.tag != .linux) return error.SkipZigTest; |
| 1513 | | 1570 | |