Skip to content

Commit de0a4cb

Browse files
committed
fix(io_uring): properly handle INTR signal
1 parent 811e4f7 commit de0a4cb

File tree

1 file changed

+47
-14
lines changed

1 file changed

+47
-14
lines changed

src/aio/apis/io_uring.zig

+47-14
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,10 @@ pub const AsyncIoUring = struct {
559559
LinuxError.BADF => .{ .err = AcceptError.InvalidFd },
560560
LinuxError.CONNABORTED => .{ .err = AcceptError.ConnectionAborted },
561561
LinuxError.FAULT => .{ .err = AcceptError.InvalidAddress },
562-
LinuxError.INTR => .{ .err = AcceptError.Interrupted },
562+
LinuxError.INTR => {
563+
try uring.queue_accept(job.task, inner.socket, inner.kind);
564+
continue;
565+
},
563566
LinuxError.INVAL => .{ .err = AcceptError.NotListening },
564567
LinuxError.MFILE => .{ .err = AcceptError.ProcessFdQuotaExceeded },
565568
LinuxError.NFILE => .{ .err = AcceptError.SystemFdQuotaExceeded },
@@ -592,7 +595,10 @@ pub const AsyncIoUring = struct {
592595
LinuxError.BADF => .{ .err = ConnectError.InvalidFd },
593596
LinuxError.CONNREFUSED => .{ .err = ConnectError.ConnectionRefused },
594597
LinuxError.FAULT => .{ .err = ConnectError.InvalidAddress },
595-
LinuxError.INTR => .{ .err = ConnectError.Interrupted },
598+
LinuxError.INTR => {
599+
try uring.queue_connect(job.task, inner.socket, inner.addr, inner.kind);
600+
continue;
601+
},
596602
LinuxError.ISCONN => .{ .err = ConnectError.AlreadyConnected },
597603
LinuxError.NETUNREACH => .{ .err = ConnectError.NetworkUnreachable },
598604
LinuxError.NOTSOCK => .{ .err = ConnectError.NotASocket },
@@ -604,7 +610,7 @@ pub const AsyncIoUring = struct {
604610

605611
break :blk .{ .connect = result };
606612
},
607-
.recv => {
613+
.recv => |inner| {
608614
if (cqe.res > 0) break :blk .{ .recv = .{ .actual = @intCast(cqe.res) } };
609615
if (cqe.res == 0) break :blk .{ .recv = .{ .err = RecvError.Closed } };
610616

@@ -616,7 +622,10 @@ pub const AsyncIoUring = struct {
616622
LinuxError.CONNRESET => .{ .err = RecvError.Closed },
617623
LinuxError.CONNREFUSED => .{ .err = RecvError.ConnectionRefused },
618624
LinuxError.FAULT => .{ .err = RecvError.InvalidAddress },
619-
LinuxError.INTR => .{ .err = RecvError.Interrupted },
625+
LinuxError.INTR => {
626+
try uring.queue_recv(job.task, inner.socket, inner.buffer);
627+
continue;
628+
},
620629
LinuxError.INVAL => .{ .err = RecvError.InvalidArguments },
621630
LinuxError.NOMEM => .{ .err = RecvError.OutOfMemory },
622631
LinuxError.NOTCONN => .{ .err = RecvError.NotConnected },
@@ -627,7 +636,7 @@ pub const AsyncIoUring = struct {
627636

628637
break :blk .{ .recv = result };
629638
},
630-
.send => {
639+
.send => |inner| {
631640
if (cqe.res >= 0) break :blk .{ .send = .{ .actual = @intCast(cqe.res) } };
632641

633642
const result: SendResult = result: {
@@ -640,7 +649,10 @@ pub const AsyncIoUring = struct {
640649
LinuxError.CONNRESET, LinuxError.PIPE => .{ .err = SendError.Closed },
641650
LinuxError.DESTADDRREQ => .{ .err = SendError.NoDestinationAddress },
642651
LinuxError.FAULT => .{ .err = SendError.InvalidAddress },
643-
LinuxError.INTR => .{ .err = SendError.Interrupted },
652+
LinuxError.INTR => {
653+
try uring.queue_send(job.task, inner.socket, inner.buffer);
654+
continue;
655+
},
644656
LinuxError.INVAL => .{ .err = SendError.InvalidArguments },
645657
LinuxError.ISCONN => .{ .err = SendError.AlreadyConnected },
646658
LinuxError.MSGSIZE => .{ .err = SendError.InvalidSize },
@@ -653,7 +665,7 @@ pub const AsyncIoUring = struct {
653665

654666
break :blk .{ .send = result };
655667
},
656-
.mkdir => |_| {
668+
.mkdir => |inner| {
657669
if (cqe.res == 0) break :blk .{ .mkdir = .{ .actual = {} } };
658670

659671
const result: MkdirResult = result: {
@@ -667,6 +679,10 @@ pub const AsyncIoUring = struct {
667679
LinuxError.NOSPC => .{ .err = MkdirError.NoSpace },
668680
LinuxError.NOTDIR => .{ .err = MkdirError.NotADirectory },
669681
LinuxError.ROFS => .{ .err = MkdirError.ReadOnlyFileSystem },
682+
LinuxError.INTR => {
683+
try uring.queue_mkdir(job.task, inner.path, inner.mode);
684+
continue;
685+
},
670686
else => .{ .err = MkdirError.Unexpected },
671687
};
672688
};
@@ -693,7 +709,10 @@ pub const AsyncIoUring = struct {
693709
LinuxError.EXIST => .{ .err = OpenError.AlreadyExists },
694710
LinuxError.FAULT => .{ .err = OpenError.InvalidAddress },
695711
LinuxError.FBIG, LinuxError.OVERFLOW => .{ .err = OpenError.FileTooBig },
696-
LinuxError.INTR => .{ .err = OpenError.Interrupted },
712+
LinuxError.INTR => {
713+
try uring.queue_open(job.task, inner.path, inner.flags);
714+
continue;
715+
},
697716
LinuxError.INVAL => .{ .err = OpenError.InvalidArguments },
698717
LinuxError.ISDIR => .{ .err = OpenError.IsDirectory },
699718
LinuxError.LOOP => .{ .err = OpenError.Loop },
@@ -715,7 +734,7 @@ pub const AsyncIoUring = struct {
715734

716735
break :blk .{ .open = result };
717736
},
718-
.delete => {
737+
.delete => |inner| {
719738
if (cqe.res == 0) break :blk .{ .delete = .{ .actual = {} } };
720739

721740
const result: DeleteResult = result: {
@@ -734,6 +753,10 @@ pub const AsyncIoUring = struct {
734753
LinuxError.NOTDIR => .{ .err = DeleteError.IsNotDirectory },
735754
LinuxError.ROFS => .{ .err = DeleteError.ReadOnlyFileSystem },
736755
LinuxError.BADF => .{ .err = DeleteError.InvalidFd },
756+
LinuxError.INTR => {
757+
try uring.queue_delete(job.task, inner.path, inner.is_dir);
758+
continue;
759+
},
737760
// rmdir
738761
LinuxError.INVAL => .{ .err = DeleteError.InvalidArguments },
739762
LinuxError.NOTEMPTY => .{ .err = DeleteError.NotEmpty },
@@ -743,7 +766,7 @@ pub const AsyncIoUring = struct {
743766

744767
break :blk .{ .delete = result };
745768
},
746-
.read => {
769+
.read => |inner| {
747770
if (cqe.res > 0) break :blk .{ .read = .{ .actual = @intCast(cqe.res) } };
748771
if (cqe.res == 0) break :blk .{ .read = .{ .err = ReadError.EndOfFile } };
749772

@@ -753,7 +776,10 @@ pub const AsyncIoUring = struct {
753776
LinuxError.AGAIN => .{ .err = ReadError.WouldBlock },
754777
LinuxError.BADF => .{ .err = ReadError.InvalidFd },
755778
LinuxError.FAULT => .{ .err = ReadError.InvalidAddress },
756-
LinuxError.INTR => .{ .err = ReadError.Interrupted },
779+
LinuxError.INTR => {
780+
try uring.queue_read(job.task, inner.fd, inner.buffer, inner.offset);
781+
continue;
782+
},
757783
LinuxError.INVAL => .{ .err = ReadError.InvalidArguments },
758784
LinuxError.IO => .{ .err = ReadError.IoError },
759785
LinuxError.ISDIR => .{ .err = ReadError.IsDirectory },
@@ -763,7 +789,7 @@ pub const AsyncIoUring = struct {
763789

764790
break :blk .{ .read = result };
765791
},
766-
.write => {
792+
.write => |inner| {
767793
if (cqe.res > 0) break :blk .{ .write = .{ .actual = @intCast(cqe.res) } };
768794

769795
const result: WriteResult = result: {
@@ -775,7 +801,10 @@ pub const AsyncIoUring = struct {
775801
LinuxError.DQUOT => .{ .err = WriteError.DiskQuotaExceeded },
776802
LinuxError.FAULT => .{ .err = WriteError.InvalidAddress },
777803
LinuxError.FBIG => .{ .err = WriteError.FileTooBig },
778-
LinuxError.INTR => .{ .err = WriteError.Interrupted },
804+
LinuxError.INTR => {
805+
try uring.queue_write(job.task, inner.fd, inner.buffer, inner.offset);
806+
continue;
807+
},
779808
LinuxError.INVAL => .{ .err = WriteError.InvalidArguments },
780809
LinuxError.IO => .{ .err = WriteError.IoError },
781810
LinuxError.NOSPC => .{ .err = WriteError.NoSpace },
@@ -787,7 +816,7 @@ pub const AsyncIoUring = struct {
787816

788817
break :blk .{ .write = result };
789818
},
790-
.stat => {
819+
.stat => |inner| {
791820
defer uring.allocator.destroy(job_with_data.statx);
792821

793822
if (cqe.res == 0) {
@@ -818,6 +847,10 @@ pub const AsyncIoUring = struct {
818847
LinuxError.BADF => .{ .err = StatError.InvalidFd },
819848
LinuxError.FAULT => .{ .err = StatError.InvalidAddress },
820849
LinuxError.INVAL => .{ .err = StatError.InvalidArguments },
850+
LinuxError.INTR => {
851+
try uring.queue_stat(job.task, inner);
852+
continue;
853+
},
821854
LinuxError.LOOP => .{ .err = StatError.Loop },
822855
LinuxError.NAMETOOLONG => .{ .err = StatError.NameTooLong },
823856
LinuxError.NOENT => .{ .err = StatError.NotFound },

0 commit comments

Comments
 (0)