| ... | ... | @@ -95,6 +95,7 @@ pub const IO_Uring = struct { |
| 95 | 95 | assert(p.*.resv[0] == 0); |
| 96 | 96 | assert(p.*.resv[1] == 0); |
| 97 | 97 | assert(p.*.resv[2] == 0); |
| 98 | if (!supported) return error.IO_UringKernelNotSupported; |
| 98 | 99 | |
| 99 | 100 | const res = linux.io_uring_setup(entries, p); |
| 100 | 101 | try check_errno(res); |
| ... | ... | @@ -346,6 +347,7 @@ pub const IO_Uring = struct { |
| 346 | 347 | addrlen: *os.socklen_t, |
| 347 | 348 | accept_flags: u32 |
| 348 | 349 | ) !*io_uring_sqe { |
| 350 | if (!can_accept) return error.IO_UringKernelCannotAccept; |
| 349 | 351 | // "sqe->fd is the file descriptor, sqe->addr holds a pointer to struct sockaddr, |
| 350 | 352 | // sqe->addr2 holds a pointer to socklen_t, and finally sqe->accept_flags holds the flags |
| 351 | 353 | // for accept(4)." - https://lwn.net/ml/linux-block/20191025173037.13486-1-axboe@kernel.dk/ |
| ... | ... | @@ -403,6 +405,7 @@ pub const IO_Uring = struct { |
| 403 | 405 | buffer: []u8, |
| 404 | 406 | offset: u64 |
| 405 | 407 | ) !*io_uring_sqe { |
| 408 | if (!can_read) return error.IO_UringKernelCannotRead; |
| 406 | 409 | const sqe = try self.get_sqe(); |
| 407 | 410 | sqe.* = .{ |
| 408 | 411 | .opcode = .READ, |
| ... | ... | @@ -424,6 +427,7 @@ pub const IO_Uring = struct { |
| 424 | 427 | buffer: []const u8, |
| 425 | 428 | offset: u64 |
| 426 | 429 | ) !*io_uring_sqe { |
| 430 | if (!can_write) return error.IO_UringKernelCannotWrite; |
| 427 | 431 | const sqe = try self.get_sqe(); |
| 428 | 432 | sqe.* = .{ |
| 429 | 433 | .opcode = .WRITE, |
| ... | ... | @@ -662,8 +666,15 @@ inline fn check_errno(res: usize) !void { |
| 662 | 666 | if (errno != 0) return os.unexpectedErrno(errno); |
| 663 | 667 | } |
| 664 | 668 | |
| 669 | const minimum = std.Target.current.os.isAtLeast; |
| 670 | pub const can_single_mmap = comptime minimum(.linux, .{ .major = 5, .minor = 4 }) == true; |
| 671 | pub const can_accept = comptime minimum(.linux, .{ .major = 5, .minor = 5 }) == true; |
| 672 | pub const can_read = comptime minimum(.linux, .{ .major = 5, .minor = 6 }) == true; |
| 673 | pub const can_write = comptime minimum(.linux, .{ .major = 5, .minor = 6 }) == true; |
| 674 | pub const supported = can_single_mmap; |
| 675 | |
| 665 | 676 | test "queue_nop" { |
| 666 | | if (builtin.os.tag != .linux) return error.SkipZigTest; |
| 677 | if (!supported) return error.SkipZigTest; |
| 667 | 678 | |
| 668 | 679 | var ring = try IO_Uring.init(1, 0); |
| 669 | 680 | defer { |
| ... | ... | @@ -726,7 +737,7 @@ test "queue_nop" { |
| 726 | 737 | } |
| 727 | 738 | |
| 728 | 739 | test "queue_readv" { |
| 729 | | if (builtin.os.tag != .linux) return error.SkipZigTest; |
| 740 | if (!supported) return error.SkipZigTest; |
| 730 | 741 | |
| 731 | 742 | var ring = try IO_Uring.init(1, 0); |
| 732 | 743 | defer ring.deinit(); |
| ... | ... | @@ -758,7 +769,7 @@ test "queue_readv" { |
| 758 | 769 | } |
| 759 | 770 | |
| 760 | 771 | test "queue_writev/queue_fsync" { |
| 761 | | if (builtin.os.tag != .linux) return error.SkipZigTest; |
| 772 | if (!supported) return error.SkipZigTest; |
| 762 | 773 | |
| 763 | 774 | var ring = try IO_Uring.init(2, 0); |
| 764 | 775 | defer ring.deinit(); |
| ... | ... | @@ -799,8 +810,7 @@ test "queue_writev/queue_fsync" { |
| 799 | 810 | } |
| 800 | 811 | |
| 801 | 812 | test "queue_write/queue_read" { |
| 802 | | if (builtin.os.tag != .linux) return error.SkipZigTest; |
| 803 | | // This test may require newer kernel versions. |
| 813 | if (!can_read or !can_write) return error.SkipZigTest; |
| 804 | 814 | |
| 805 | 815 | var ring = try IO_Uring.init(2, 0); |
| 806 | 816 | defer ring.deinit(); |