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 {...@@ -1020,9 +1020,43 @@ pub const Loop = struct {
1020 }1020 }
1021 }1021 }
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
1023 /// Performs an async `os.pwritev` using a separate thread.1057 /// Performs an async `os.pwritev` using a separate thread.
1024 /// `fd` must block and not return EAGAIN.1058 /// `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 {
1026 var req_node = Request.Node{1060 var req_node = Request.Node{
1027 .data = .{1061 .data = .{
1028 .msg = .{1062 .msg = .{
...@@ -1194,6 +1228,9 @@ pub const Loop = struct {...@@ -1194,6 +1228,9 @@ pub const Loop = struct {
1194 .writev => |*msg| {1228 .writev => |*msg| {
1195 msg.result = os.writev(msg.fd, msg.iov);1229 msg.result = os.writev(msg.fd, msg.iov);
1196 },1230 },
1231 .pwrite => |*msg| {
1232 msg.result = os.pwrite(msg.fd, msg.bytes, msg.offset);
1233 },
1197 .pwritev => |*msg| {1234 .pwritev => |*msg| {
1198 msg.result = os.pwritev(msg.fd, msg.iov, msg.offset);1235 msg.result = os.pwritev(msg.fd, msg.iov, msg.offset);
1199 },1236 },
...@@ -1263,6 +1300,7 @@ pub const Loop = struct {...@@ -1263,6 +1300,7 @@ pub const Loop = struct {
1263 readv: ReadV,1300 readv: ReadV,
1264 write: Write,1301 write: Write,
1265 writev: WriteV,1302 writev: WriteV,
1303 pwrite: PWrite,
1266 pwritev: PWriteV,1304 pwritev: PWriteV,
1267 pread: PRead,1305 pread: PRead,
1268 preadv: PReadV,1306 preadv: PReadV,
...@@ -1306,6 +1344,15 @@ pub const Loop = struct {...@@ -1306,6 +1344,15 @@ pub const Loop = struct {
1306 pub const Error = os.WriteError;1344 pub const Error = os.WriteError;
1307 };1345 };
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
1309 pub const PWriteV = struct {1356 pub const PWriteV = struct {
1310 fd: os.fd_t,1357 fd: os.fd_t,
1311 iov: []const os.iovec_const,1358 iov: []const os.iovec_const,
lib/std/fs/file.zig+5-3
...@@ -566,10 +566,12 @@ pub const File = struct {...@@ -566,10 +566,12 @@ pub const File = struct {
566 pub fn pwrite(self: File, bytes: []const u8, offset: u64) PWriteError!usize {566 pub fn pwrite(self: File, bytes: []const u8, offset: u64) PWriteError!usize {
567 if (is_windows) {567 if (is_windows) {
568 return windows.WriteFile(self.handle, bytes, offset, self.intended_io_mode);568 return windows.WriteFile(self.handle, bytes, offset, self.intended_io_mode);
569 } else if (self.capable_io_mode != self.intended_io_mode) {569 }
570 return std.event.Loop.instance.?.pwrite(self.handle, bytes, offset);570
571 } else {571 if (self.intended_io_mode == .blocking) {
572 return os.pwrite(self.handle, bytes, offset);572 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);
573 }575 }
574 }576 }
575577
lib/std/os.zig+1-6
...@@ -875,12 +875,7 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize {...@@ -875,12 +875,7 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize {
875 EINTR => continue,875 EINTR => continue,
876 EINVAL => unreachable,876 EINVAL => unreachable,
877 EFAULT => unreachable,877 EFAULT => unreachable,
878 EAGAIN => if (std.event.Loop.instance) |loop| {878 EAGAIN => return error.WouldBlock,
879 loop.waitUntilFdWritable(fd);
880 continue;
881 } else {
882 return error.WouldBlock;
883 },
884 EBADF => return error.NotOpenForWriting, // Can be a race condition.879 EBADF => return error.NotOpenForWriting, // Can be a race condition.
885 EDESTADDRREQ => unreachable, // `connect` was never called.880 EDESTADDRREQ => unreachable, // `connect` was never called.
886 EDQUOT => return error.DiskQuota,881 EDQUOT => return error.DiskQuota,