authorgravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2020-06-20 00:17:10+02:00
committergravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2020-09-24 22:06:21+02:00
log7a07c62a075ada32c5eca298e4ed6a4c8a14cf89
tree9d0d5d7c1c41d1bde2bc2e7ef7d0bd9e44cf3f94
parent18f6629bd8ad8bd13108ddce82c32baf6f53628e

pwrite

Signed-off-by: Loris Cro <kappaloris@gmail.com>

3 files changed, 54 insertions(+), 10 deletions(-)

lib/std/event/loop.zig+48-1
......@@ -1020,9 +1020,43 @@ pub const Loop = struct {
10201020 }
10211021 }
10221022
1023 /// Performs an async `os.pwrite` using a separate thread.
1024 /// `fd` must block and not return EAGAIN.
1025 pub fn pwrite(self: *Loop, fd: os.fd_t, bytes: []const u8, offset: u64, simulate_evented: bool) os.PWriteError!usize {
1026 if (simulate_evented) {
1027 var req_node = Request.Node{
1028 .data = .{
1029 .msg = .{
1030 .pwrite = .{
1031 .fd = fd,
1032 .bytes = bytes,
1033 .offset = offset,
1034 .result = undefined,
1035 },
1036 },
1037 .finish = .{ .TickNode = .{ .data = @frame() } },
1038 },
1039 };
1040 suspend {
1041 self.posixFsRequest(&req_node);
1042 }
1043 return req_node.data.msg.pwrite.result;
1044 } else {
1045 while (true) {
1046 return os.pwrite(fd, bytes, offset) catch |err| switch (err) {
1047 error.WouldBlock => {
1048 self.waitUntilFdWritable(fd);
1049 continue;
1050 },
1051 else => return err,
1052 };
1053 }
1054 }
1055 }
1056
10231057 /// Performs an async `os.pwritev` using a separate thread.
10241058 /// `fd` must block and not return EAGAIN.
1025 pub fn pwritev(self: *Loop, fd: os.fd_t, iov: []const os.iovec_const, offset: u64) os.WriteError!usize {
1059 pub fn pwritev(self: *Loop, fd: os.fd_t, iov: []const os.iovec_const, offset: u64) os.PWriteError!usize {
10261060 var req_node = Request.Node{
10271061 .data = .{
10281062 .msg = .{
......@@ -1194,6 +1228,9 @@ pub const Loop = struct {
11941228 .writev => |*msg| {
11951229 msg.result = os.writev(msg.fd, msg.iov);
11961230 },
1231 .pwrite => |*msg| {
1232 msg.result = os.pwrite(msg.fd, msg.bytes, msg.offset);
1233 },
11971234 .pwritev => |*msg| {
11981235 msg.result = os.pwritev(msg.fd, msg.iov, msg.offset);
11991236 },
......@@ -1263,6 +1300,7 @@ pub const Loop = struct {
12631300 readv: ReadV,
12641301 write: Write,
12651302 writev: WriteV,
1303 pwrite: PWrite,
12661304 pwritev: PWriteV,
12671305 pread: PRead,
12681306 preadv: PReadV,
......@@ -1306,6 +1344,15 @@ pub const Loop = struct {
13061344 pub const Error = os.WriteError;
13071345 };
13081346
1347 pub const PWrite = struct {
1348 fd: os.fd_t,
1349 bytes: []const u8,
1350 offset: usize,
1351 result: Error!usize,
1352
1353 pub const Error = os.PWriteError;
1354 };
1355
13091356 pub const PWriteV = struct {
13101357 fd: os.fd_t,
13111358 iov: []const os.iovec_const,
lib/std/fs/file.zig+5-3
......@@ -566,10 +566,12 @@ pub const File = struct {
566566 pub fn pwrite(self: File, bytes: []const u8, offset: u64) PWriteError!usize {
567567 if (is_windows) {
568568 return windows.WriteFile(self.handle, bytes, offset, self.intended_io_mode);
569 } else if (self.capable_io_mode != self.intended_io_mode) {
570 return std.event.Loop.instance.?.pwrite(self.handle, bytes, offset);
571 } else {
569 }
570
571 if (self.intended_io_mode == .blocking) {
572572 return os.pwrite(self.handle, bytes, offset);
573 } else {
574 return std.event.Loop.instance.?.pwrite(self.handle, bytes, offset, self.capable_io_mode != self.intended_io_mode);
573575 }
574576 }
575577
lib/std/os.zig+1-6
......@@ -875,12 +875,7 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize {
875875 EINTR => continue,
876876 EINVAL => unreachable,
877877 EFAULT => unreachable,
878 EAGAIN => if (std.event.Loop.instance) |loop| {
879 loop.waitUntilFdWritable(fd);
880 continue;
881 } else {
882 return error.WouldBlock;
883 },
878 EAGAIN => return error.WouldBlock,
884879 EBADF => return error.NotOpenForWriting, // Can be a race condition.
885880 EDESTADDRREQ => unreachable, // `connect` was never called.
886881 EDQUOT => return error.DiskQuota,