| ... | @@ -23,6 +23,7 @@ pub const Request = struct { | ... | @@ -23,6 +23,7 @@ pub const Request = struct { |
| 23 | }; | 23 | }; |
| 24 | | 24 | |
| 25 | pub const Msg = union(enum) { | 25 | pub const Msg = union(enum) { |
| | 26 | WriteV: WriteV, |
| 26 | PWriteV: PWriteV, | 27 | PWriteV: PWriteV, |
| 27 | PReadV: PReadV, | 28 | PReadV: PReadV, |
| 28 | Open: Open, | 29 | Open: Open, |
| ... | @@ -30,6 +31,14 @@ pub const Request = struct { | ... | @@ -30,6 +31,14 @@ pub const Request = struct { |
| 30 | WriteFile: WriteFile, | 31 | WriteFile: WriteFile, |
| 31 | End, // special - means the fs thread should exit | 32 | End, // special - means the fs thread should exit |
| 32 | | 33 | |
| | 34 | pub const WriteV = struct { |
| | 35 | fd: fd_t, |
| | 36 | iov: []const os.iovec_const, |
| | 37 | result: Error!void, |
| | 38 | |
| | 39 | pub const Error = os.WriteError; |
| | 40 | }; |
| | 41 | |
| 33 | pub const PWriteV = struct { | 42 | pub const PWriteV = struct { |
| 34 | fd: fd_t, | 43 | fd: fd_t, |
| 35 | iov: []const os.iovec_const, | 44 | iov: []const os.iovec_const, |
| ... | @@ -77,7 +86,7 @@ pub const Request = struct { | ... | @@ -77,7 +86,7 @@ pub const Request = struct { |
| 77 | pub const PWriteVError = error{OutOfMemory} || File.WriteError; | 86 | pub const PWriteVError = error{OutOfMemory} || File.WriteError; |
| 78 | | 87 | |
| 79 | /// data - just the inner references - must live until pwritev frame completes. | 88 | /// data - just the inner references - must live until pwritev frame completes. |
| 80 | pub async fn pwritev(loop: *Loop, fd: fd_t, data: []const []const u8, offset: usize) PWriteVError!void { | 89 | pub fn pwritev(loop: *Loop, fd: fd_t, data: []const []const u8, offset: usize) PWriteVError!void { |
| 81 | switch (builtin.os) { | 90 | switch (builtin.os) { |
| 82 | .macosx, | 91 | .macosx, |
| 83 | .linux, | 92 | .linux, |
| ... | @@ -94,31 +103,31 @@ pub async fn pwritev(loop: *Loop, fd: fd_t, data: []const []const u8, offset: us | ... | @@ -94,31 +103,31 @@ pub async fn pwritev(loop: *Loop, fd: fd_t, data: []const []const u8, offset: us |
| 94 | }; | 103 | }; |
| 95 | } | 104 | } |
| 96 | | 105 | |
| 97 | return await (async pwritevPosix(loop, fd, iovecs, offset) catch unreachable); | 106 | return pwritevPosix(loop, fd, iovecs, offset); |
| 98 | }, | 107 | }, |
| 99 | .windows => { | 108 | .windows => { |
| 100 | const data_copy = try std.mem.dupe(loop.allocator, []const u8, data); | 109 | const data_copy = try std.mem.dupe(loop.allocator, []const u8, data); |
| 101 | defer loop.allocator.free(data_copy); | 110 | defer loop.allocator.free(data_copy); |
| 102 | return await (async pwritevWindows(loop, fd, data, offset) catch unreachable); | 111 | return pwritevWindows(loop, fd, data, offset); |
| 103 | }, | 112 | }, |
| 104 | else => @compileError("Unsupported OS"), | 113 | else => @compileError("Unsupported OS"), |
| 105 | } | 114 | } |
| 106 | } | 115 | } |
| 107 | | 116 | |
| 108 | /// data must outlive the returned frame | 117 | /// data must outlive the returned frame |
| 109 | pub async fn pwritevWindows(loop: *Loop, fd: fd_t, data: []const []const u8, offset: usize) os.WindowsWriteError!void { | 118 | pub fn pwritevWindows(loop: *Loop, fd: fd_t, data: []const []const u8, offset: usize) os.WindowsWriteError!void { |
| 110 | if (data.len == 0) return; | 119 | if (data.len == 0) return; |
| 111 | if (data.len == 1) return await (async pwriteWindows(loop, fd, data[0], offset) catch unreachable); | 120 | if (data.len == 1) return pwriteWindows(loop, fd, data[0], offset); |
| 112 | | 121 | |
| 113 | // TODO do these in parallel | 122 | // TODO do these in parallel |
| 114 | var off = offset; | 123 | var off = offset; |
| 115 | for (data) |buf| { | 124 | for (data) |buf| { |
| 116 | try await (async pwriteWindows(loop, fd, buf, off) catch unreachable); | 125 | try pwriteWindows(loop, fd, buf, off); |
| 117 | off += buf.len; | 126 | off += buf.len; |
| 118 | } | 127 | } |
| 119 | } | 128 | } |
| 120 | | 129 | |
| 121 | pub async fn pwriteWindows(loop: *Loop, fd: fd_t, data: []const u8, offset: u64) os.WindowsWriteError!void { | 130 | pub fn pwriteWindows(loop: *Loop, fd: fd_t, data: []const u8, offset: u64) os.WindowsWriteError!void { |
| 122 | var resume_node = Loop.ResumeNode.Basic{ | 131 | var resume_node = Loop.ResumeNode.Basic{ |
| 123 | .base = Loop.ResumeNode{ | 132 | .base = Loop.ResumeNode{ |
| 124 | .id = Loop.ResumeNode.Id.Basic, | 133 | .id = Loop.ResumeNode.Id.Basic, |
| ... | @@ -158,7 +167,7 @@ pub async fn pwriteWindows(loop: *Loop, fd: fd_t, data: []const u8, offset: u64) | ... | @@ -158,7 +167,7 @@ pub async fn pwriteWindows(loop: *Loop, fd: fd_t, data: []const u8, offset: u64) |
| 158 | } | 167 | } |
| 159 | | 168 | |
| 160 | /// iovecs must live until pwritev frame completes. | 169 | /// iovecs must live until pwritev frame completes. |
| 161 | pub async fn pwritevPosix( | 170 | pub fn pwritevPosix( |
| 162 | loop: *Loop, | 171 | loop: *Loop, |
| 163 | fd: fd_t, | 172 | fd: fd_t, |
| 164 | iovecs: []const os.iovec_const, | 173 | iovecs: []const os.iovec_const, |
| ... | @@ -195,10 +204,44 @@ pub async fn pwritevPosix( | ... | @@ -195,10 +204,44 @@ pub async fn pwritevPosix( |
| 195 | return req_node.data.msg.PWriteV.result; | 204 | return req_node.data.msg.PWriteV.result; |
| 196 | } | 205 | } |
| 197 | | 206 | |
| | 207 | /// iovecs must live until pwritev frame completes. |
| | 208 | pub fn writevPosix( |
| | 209 | loop: *Loop, |
| | 210 | fd: fd_t, |
| | 211 | iovecs: []const os.iovec_const, |
| | 212 | ) os.WriteError!void { |
| | 213 | var req_node = RequestNode{ |
| | 214 | .prev = null, |
| | 215 | .next = null, |
| | 216 | .data = Request{ |
| | 217 | .msg = Request.Msg{ |
| | 218 | .WriteV = Request.Msg.WriteV{ |
| | 219 | .fd = fd, |
| | 220 | .iov = iovecs, |
| | 221 | .result = undefined, |
| | 222 | }, |
| | 223 | }, |
| | 224 | .finish = Request.Finish{ |
| | 225 | .TickNode = Loop.NextTickNode{ |
| | 226 | .prev = null, |
| | 227 | .next = null, |
| | 228 | .data = @frame(), |
| | 229 | }, |
| | 230 | }, |
| | 231 | }, |
| | 232 | }; |
| | 233 | |
| | 234 | suspend { |
| | 235 | loop.posixFsRequest(&req_node); |
| | 236 | } |
| | 237 | |
| | 238 | return req_node.data.msg.WriteV.result; |
| | 239 | } |
| | 240 | |
| 198 | pub const PReadVError = error{OutOfMemory} || File.ReadError; | 241 | pub const PReadVError = error{OutOfMemory} || File.ReadError; |
| 199 | | 242 | |
| 200 | /// data - just the inner references - must live until preadv frame completes. | 243 | /// data - just the inner references - must live until preadv frame completes. |
| 201 | pub async fn preadv(loop: *Loop, fd: fd_t, data: []const []u8, offset: usize) PReadVError!usize { | 244 | pub fn preadv(loop: *Loop, fd: fd_t, data: []const []u8, offset: usize) PReadVError!usize { |
| 202 | assert(data.len != 0); | 245 | assert(data.len != 0); |
| 203 | switch (builtin.os) { | 246 | switch (builtin.os) { |
| 204 | .macosx, | 247 | .macosx, |
| ... | @@ -216,21 +259,21 @@ pub async fn preadv(loop: *Loop, fd: fd_t, data: []const []u8, offset: usize) PR | ... | @@ -216,21 +259,21 @@ pub async fn preadv(loop: *Loop, fd: fd_t, data: []const []u8, offset: usize) PR |
| 216 | }; | 259 | }; |
| 217 | } | 260 | } |
| 218 | | 261 | |
| 219 | return await (async preadvPosix(loop, fd, iovecs, offset) catch unreachable); | 262 | return preadvPosix(loop, fd, iovecs, offset); |
| 220 | }, | 263 | }, |
| 221 | .windows => { | 264 | .windows => { |
| 222 | const data_copy = try std.mem.dupe(loop.allocator, []u8, data); | 265 | const data_copy = try std.mem.dupe(loop.allocator, []u8, data); |
| 223 | defer loop.allocator.free(data_copy); | 266 | defer loop.allocator.free(data_copy); |
| 224 | return await (async preadvWindows(loop, fd, data_copy, offset) catch unreachable); | 267 | return preadvWindows(loop, fd, data_copy, offset); |
| 225 | }, | 268 | }, |
| 226 | else => @compileError("Unsupported OS"), | 269 | else => @compileError("Unsupported OS"), |
| 227 | } | 270 | } |
| 228 | } | 271 | } |
| 229 | | 272 | |
| 230 | /// data must outlive the returned frame | 273 | /// data must outlive the returned frame |
| 231 | pub async fn preadvWindows(loop: *Loop, fd: fd_t, data: []const []u8, offset: u64) !usize { | 274 | pub fn preadvWindows(loop: *Loop, fd: fd_t, data: []const []u8, offset: u64) !usize { |
| 232 | assert(data.len != 0); | 275 | assert(data.len != 0); |
| 233 | if (data.len == 1) return await (async preadWindows(loop, fd, data[0], offset) catch unreachable); | 276 | if (data.len == 1) return preadWindows(loop, fd, data[0], offset); |
| 234 | | 277 | |
| 235 | // TODO do these in parallel? | 278 | // TODO do these in parallel? |
| 236 | var off: usize = 0; | 279 | var off: usize = 0; |
| ... | @@ -238,7 +281,7 @@ pub async fn preadvWindows(loop: *Loop, fd: fd_t, data: []const []u8, offset: u6 | ... | @@ -238,7 +281,7 @@ pub async fn preadvWindows(loop: *Loop, fd: fd_t, data: []const []u8, offset: u6 |
| 238 | var inner_off: usize = 0; | 281 | var inner_off: usize = 0; |
| 239 | while (true) { | 282 | while (true) { |
| 240 | const v = data[iov_i]; | 283 | const v = data[iov_i]; |
| 241 | const amt_read = try await (async preadWindows(loop, fd, v[inner_off .. v.len - inner_off], offset + off) catch unreachable); | 284 | const amt_read = try preadWindows(loop, fd, v[inner_off .. v.len - inner_off], offset + off); |
| 242 | off += amt_read; | 285 | off += amt_read; |
| 243 | inner_off += amt_read; | 286 | inner_off += amt_read; |
| 244 | if (inner_off == v.len) { | 287 | if (inner_off == v.len) { |
| ... | @@ -252,7 +295,7 @@ pub async fn preadvWindows(loop: *Loop, fd: fd_t, data: []const []u8, offset: u6 | ... | @@ -252,7 +295,7 @@ pub async fn preadvWindows(loop: *Loop, fd: fd_t, data: []const []u8, offset: u6 |
| 252 | } | 295 | } |
| 253 | } | 296 | } |
| 254 | | 297 | |
| 255 | pub async fn preadWindows(loop: *Loop, fd: fd_t, data: []u8, offset: u64) !usize { | 298 | pub fn preadWindows(loop: *Loop, fd: fd_t, data: []u8, offset: u64) !usize { |
| 256 | var resume_node = Loop.ResumeNode.Basic{ | 299 | var resume_node = Loop.ResumeNode.Basic{ |
| 257 | .base = Loop.ResumeNode{ | 300 | .base = Loop.ResumeNode{ |
| 258 | .id = Loop.ResumeNode.Id.Basic, | 301 | .id = Loop.ResumeNode.Id.Basic, |
| ... | @@ -291,7 +334,7 @@ pub async fn preadWindows(loop: *Loop, fd: fd_t, data: []u8, offset: u64) !usize | ... | @@ -291,7 +334,7 @@ pub async fn preadWindows(loop: *Loop, fd: fd_t, data: []u8, offset: u64) !usize |
| 291 | } | 334 | } |
| 292 | | 335 | |
| 293 | /// iovecs must live until preadv frame completes | 336 | /// iovecs must live until preadv frame completes |
| 294 | pub async fn preadvPosix( | 337 | pub fn preadvPosix( |
| 295 | loop: *Loop, | 338 | loop: *Loop, |
| 296 | fd: fd_t, | 339 | fd: fd_t, |
| 297 | iovecs: []const os.iovec, | 340 | iovecs: []const os.iovec, |
| ... | @@ -328,7 +371,7 @@ pub async fn preadvPosix( | ... | @@ -328,7 +371,7 @@ pub async fn preadvPosix( |
| 328 | return req_node.data.msg.PReadV.result; | 371 | return req_node.data.msg.PReadV.result; |
| 329 | } | 372 | } |
| 330 | | 373 | |
| 331 | pub async fn openPosix( | 374 | pub fn openPosix( |
| 332 | loop: *Loop, | 375 | loop: *Loop, |
| 333 | path: []const u8, | 376 | path: []const u8, |
| 334 | flags: u32, | 377 | flags: u32, |
| ... | @@ -367,11 +410,11 @@ pub async fn openPosix( | ... | @@ -367,11 +410,11 @@ pub async fn openPosix( |
| 367 | return req_node.data.msg.Open.result; | 410 | return req_node.data.msg.Open.result; |
| 368 | } | 411 | } |
| 369 | | 412 | |
| 370 | pub async fn openRead(loop: *Loop, path: []const u8) File.OpenError!fd_t { | 413 | pub fn openRead(loop: *Loop, path: []const u8) File.OpenError!fd_t { |
| 371 | switch (builtin.os) { | 414 | switch (builtin.os) { |
| 372 | .macosx, .linux, .freebsd, .netbsd => { | 415 | .macosx, .linux, .freebsd, .netbsd => { |
| 373 | const flags = os.O_LARGEFILE | os.O_RDONLY | os.O_CLOEXEC; | 416 | const flags = os.O_LARGEFILE | os.O_RDONLY | os.O_CLOEXEC; |
| 374 | return await (async openPosix(loop, path, flags, File.default_mode) catch unreachable); | 417 | return openPosix(loop, path, flags, File.default_mode); |
| 375 | }, | 418 | }, |
| 376 | | 419 | |
| 377 | .windows => return windows.CreateFile( | 420 | .windows => return windows.CreateFile( |
| ... | @@ -390,12 +433,12 @@ pub async fn openRead(loop: *Loop, path: []const u8) File.OpenError!fd_t { | ... | @@ -390,12 +433,12 @@ pub async fn openRead(loop: *Loop, path: []const u8) File.OpenError!fd_t { |
| 390 | | 433 | |
| 391 | /// Creates if does not exist. Truncates the file if it exists. | 434 | /// Creates if does not exist. Truncates the file if it exists. |
| 392 | /// Uses the default mode. | 435 | /// Uses the default mode. |
| 393 | pub async fn openWrite(loop: *Loop, path: []const u8) File.OpenError!fd_t { | 436 | pub fn openWrite(loop: *Loop, path: []const u8) File.OpenError!fd_t { |
| 394 | return await (async openWriteMode(loop, path, File.default_mode) catch unreachable); | 437 | return openWriteMode(loop, path, File.default_mode); |
| 395 | } | 438 | } |
| 396 | | 439 | |
| 397 | /// Creates if does not exist. Truncates the file if it exists. | 440 | /// Creates if does not exist. Truncates the file if it exists. |
| 398 | pub async fn openWriteMode(loop: *Loop, path: []const u8, mode: File.Mode) File.OpenError!fd_t { | 441 | pub fn openWriteMode(loop: *Loop, path: []const u8, mode: File.Mode) File.OpenError!fd_t { |
| 399 | switch (builtin.os) { | 442 | switch (builtin.os) { |
| 400 | .macosx, | 443 | .macosx, |
| 401 | .linux, | 444 | .linux, |
| ... | @@ -403,7 +446,7 @@ pub async fn openWriteMode(loop: *Loop, path: []const u8, mode: File.Mode) File. | ... | @@ -403,7 +446,7 @@ pub async fn openWriteMode(loop: *Loop, path: []const u8, mode: File.Mode) File. |
| 403 | .netbsd, | 446 | .netbsd, |
| 404 | => { | 447 | => { |
| 405 | const flags = os.O_LARGEFILE | os.O_WRONLY | os.O_CREAT | os.O_CLOEXEC | os.O_TRUNC; | 448 | const flags = os.O_LARGEFILE | os.O_WRONLY | os.O_CREAT | os.O_CLOEXEC | os.O_TRUNC; |
| 406 | return await (async openPosix(loop, path, flags, File.default_mode) catch unreachable); | 449 | return openPosix(loop, path, flags, File.default_mode); |
| 407 | }, | 450 | }, |
| 408 | .windows => return windows.CreateFile( | 451 | .windows => return windows.CreateFile( |
| 409 | path, | 452 | path, |
| ... | @@ -419,7 +462,7 @@ pub async fn openWriteMode(loop: *Loop, path: []const u8, mode: File.Mode) File. | ... | @@ -419,7 +462,7 @@ pub async fn openWriteMode(loop: *Loop, path: []const u8, mode: File.Mode) File. |
| 419 | } | 462 | } |
| 420 | | 463 | |
| 421 | /// Creates if does not exist. Does not truncate. | 464 | /// Creates if does not exist. Does not truncate. |
| 422 | pub async fn openReadWrite( | 465 | pub fn openReadWrite( |
| 423 | loop: *Loop, | 466 | loop: *Loop, |
| 424 | path: []const u8, | 467 | path: []const u8, |
| 425 | mode: File.Mode, | 468 | mode: File.Mode, |
| ... | @@ -427,7 +470,7 @@ pub async fn openReadWrite( | ... | @@ -427,7 +470,7 @@ pub async fn openReadWrite( |
| 427 | switch (builtin.os) { | 470 | switch (builtin.os) { |
| 428 | .macosx, .linux, .freebsd, .netbsd => { | 471 | .macosx, .linux, .freebsd, .netbsd => { |
| 429 | const flags = os.O_LARGEFILE | os.O_RDWR | os.O_CREAT | os.O_CLOEXEC; | 472 | const flags = os.O_LARGEFILE | os.O_RDWR | os.O_CREAT | os.O_CLOEXEC; |
| 430 | return await (async openPosix(loop, path, flags, mode) catch unreachable); | 473 | return openPosix(loop, path, flags, mode); |
| 431 | }, | 474 | }, |
| 432 | | 475 | |
| 433 | .windows => return windows.CreateFile( | 476 | .windows => return windows.CreateFile( |
| ... | @@ -576,24 +619,24 @@ pub const CloseOperation = struct { | ... | @@ -576,24 +619,24 @@ pub const CloseOperation = struct { |
| 576 | | 619 | |
| 577 | /// contents must remain alive until writeFile completes. | 620 | /// contents must remain alive until writeFile completes. |
| 578 | /// TODO make this atomic or provide writeFileAtomic and rename this one to writeFileTruncate | 621 | /// TODO make this atomic or provide writeFileAtomic and rename this one to writeFileTruncate |
| 579 | pub async fn writeFile(loop: *Loop, path: []const u8, contents: []const u8) !void { | 622 | pub fn writeFile(loop: *Loop, path: []const u8, contents: []const u8) !void { |
| 580 | return await (async writeFileMode(loop, path, contents, File.default_mode) catch unreachable); | 623 | return writeFileMode(loop, path, contents, File.default_mode); |
| 581 | } | 624 | } |
| 582 | | 625 | |
| 583 | /// contents must remain alive until writeFile completes. | 626 | /// contents must remain alive until writeFile completes. |
| 584 | pub async fn writeFileMode(loop: *Loop, path: []const u8, contents: []const u8, mode: File.Mode) !void { | 627 | pub fn writeFileMode(loop: *Loop, path: []const u8, contents: []const u8, mode: File.Mode) !void { |
| 585 | switch (builtin.os) { | 628 | switch (builtin.os) { |
| 586 | .linux, | 629 | .linux, |
| 587 | .macosx, | 630 | .macosx, |
| 588 | .freebsd, | 631 | .freebsd, |
| 589 | .netbsd, | 632 | .netbsd, |
| 590 | => return await (async writeFileModeThread(loop, path, contents, mode) catch unreachable), | 633 | => return writeFileModeThread(loop, path, contents, mode), |
| 591 | .windows => return await (async writeFileWindows(loop, path, contents) catch unreachable), | 634 | .windows => return writeFileWindows(loop, path, contents), |
| 592 | else => @compileError("Unsupported OS"), | 635 | else => @compileError("Unsupported OS"), |
| 593 | } | 636 | } |
| 594 | } | 637 | } |
| 595 | | 638 | |
| 596 | async fn writeFileWindows(loop: *Loop, path: []const u8, contents: []const u8) !void { | 639 | fn writeFileWindows(loop: *Loop, path: []const u8, contents: []const u8) !void { |
| 597 | const handle = try windows.CreateFile( | 640 | const handle = try windows.CreateFile( |
| 598 | path, | 641 | path, |
| 599 | windows.GENERIC_WRITE, | 642 | windows.GENERIC_WRITE, |
| ... | @@ -605,10 +648,10 @@ async fn writeFileWindows(loop: *Loop, path: []const u8, contents: []const u8) ! | ... | @@ -605,10 +648,10 @@ async fn writeFileWindows(loop: *Loop, path: []const u8, contents: []const u8) ! |
| 605 | ); | 648 | ); |
| 606 | defer os.close(handle); | 649 | defer os.close(handle); |
| 607 | | 650 | |
| 608 | try await (async pwriteWindows(loop, handle, contents, 0) catch unreachable); | 651 | try pwriteWindows(loop, handle, contents, 0); |
| 609 | } | 652 | } |
| 610 | | 653 | |
| 611 | async fn writeFileModeThread(loop: *Loop, path: []const u8, contents: []const u8, mode: File.Mode) !void { | 654 | fn writeFileModeThread(loop: *Loop, path: []const u8, contents: []const u8, mode: File.Mode) !void { |
| 612 | const path_with_null = try std.cstr.addNullByte(loop.allocator, path); | 655 | const path_with_null = try std.cstr.addNullByte(loop.allocator, path); |
| 613 | defer loop.allocator.free(path_with_null); | 656 | defer loop.allocator.free(path_with_null); |
| 614 | | 657 | |
| ... | @@ -646,11 +689,11 @@ async fn writeFileModeThread(loop: *Loop, path: []const u8, contents: []const u8 | ... | @@ -646,11 +689,11 @@ async fn writeFileModeThread(loop: *Loop, path: []const u8, contents: []const u8 |
| 646 | /// The frame resumes when the last data has been confirmed written, but before the file handle | 689 | /// The frame resumes when the last data has been confirmed written, but before the file handle |
| 647 | /// is closed. | 690 | /// is closed. |
| 648 | /// Caller owns returned memory. | 691 | /// Caller owns returned memory. |
| 649 | pub async fn readFile(loop: *Loop, file_path: []const u8, max_size: usize) ![]u8 { | 692 | pub fn readFile(loop: *Loop, file_path: []const u8, max_size: usize) ![]u8 { |
| 650 | var close_op = try CloseOperation.start(loop); | 693 | var close_op = try CloseOperation.start(loop); |
| 651 | defer close_op.finish(); | 694 | defer close_op.finish(); |
| 652 | | 695 | |
| 653 | const fd = try await (async openRead(loop, file_path) catch unreachable); | 696 | const fd = try openRead(loop, file_path); |
| 654 | close_op.setHandle(fd); | 697 | close_op.setHandle(fd); |
| 655 | | 698 | |
| 656 | var list = std.ArrayList(u8).init(loop.allocator); | 699 | var list = std.ArrayList(u8).init(loop.allocator); |
| ... | @@ -660,7 +703,7 @@ pub async fn readFile(loop: *Loop, file_path: []const u8, max_size: usize) ![]u8 | ... | @@ -660,7 +703,7 @@ pub async fn readFile(loop: *Loop, file_path: []const u8, max_size: usize) ![]u8 |
| 660 | try list.ensureCapacity(list.len + mem.page_size); | 703 | try list.ensureCapacity(list.len + mem.page_size); |
| 661 | const buf = list.items[list.len..]; | 704 | const buf = list.items[list.len..]; |
| 662 | const buf_array = [_][]u8{buf}; | 705 | const buf_array = [_][]u8{buf}; |
| 663 | const amt = try await (async preadv(loop, fd, buf_array, list.len) catch unreachable); | 706 | const amt = try preadv(loop, fd, buf_array, list.len); |
| 664 | list.len += amt; | 707 | list.len += amt; |
| 665 | if (list.len > max_size) { | 708 | if (list.len > max_size) { |
| 666 | return error.FileTooBig; | 709 | return error.FileTooBig; |
| ... | @@ -1273,11 +1316,11 @@ const test_tmp_dir = "std_event_fs_test"; | ... | @@ -1273,11 +1316,11 @@ const test_tmp_dir = "std_event_fs_test"; |
| 1273 | // return result; | 1316 | // return result; |
| 1274 | //} | 1317 | //} |
| 1275 | | 1318 | |
| 1276 | async fn testFsWatchCantFail(loop: *Loop, result: *(anyerror!void)) void { | 1319 | fn testFsWatchCantFail(loop: *Loop, result: *(anyerror!void)) void { |
| 1277 | result.* = await (async testFsWatch(loop) catch unreachable); | 1320 | result.* = testFsWatch(loop); |
| 1278 | } | 1321 | } |
| 1279 | | 1322 | |
| 1280 | async fn testFsWatch(loop: *Loop) !void { | 1323 | fn testFsWatch(loop: *Loop) !void { |
| 1281 | const file_path = try std.fs.path.join(loop.allocator, [][]const u8{ test_tmp_dir, "file.txt" }); | 1324 | const file_path = try std.fs.path.join(loop.allocator, [][]const u8{ test_tmp_dir, "file.txt" }); |
| 1282 | defer loop.allocator.free(file_path); | 1325 | defer loop.allocator.free(file_path); |
| 1283 | | 1326 | |
| ... | @@ -1288,27 +1331,27 @@ async fn testFsWatch(loop: *Loop) !void { | ... | @@ -1288,27 +1331,27 @@ async fn testFsWatch(loop: *Loop) !void { |
| 1288 | const line2_offset = 7; | 1331 | const line2_offset = 7; |
| 1289 | | 1332 | |
| 1290 | // first just write then read the file | 1333 | // first just write then read the file |
| 1291 | try await try async writeFile(loop, file_path, contents); | 1334 | try writeFile(loop, file_path, contents); |
| 1292 | | 1335 | |
| 1293 | const read_contents = try await try async readFile(loop, file_path, 1024 * 1024); | 1336 | const read_contents = try readFile(loop, file_path, 1024 * 1024); |
| 1294 | testing.expectEqualSlices(u8, contents, read_contents); | 1337 | testing.expectEqualSlices(u8, contents, read_contents); |
| 1295 | | 1338 | |
| 1296 | // now watch the file | 1339 | // now watch the file |
| 1297 | var watch = try Watch(void).create(loop, 0); | 1340 | var watch = try Watch(void).create(loop, 0); |
| 1298 | defer watch.destroy(); | 1341 | defer watch.destroy(); |
| 1299 | | 1342 | |
| 1300 | testing.expect((try await try async watch.addFile(file_path, {})) == null); | 1343 | testing.expect((try watch.addFile(file_path, {})) == null); |
| 1301 | | 1344 | |
| 1302 | const ev = try async watch.channel.get(); | 1345 | const ev = async watch.channel.get(); |
| 1303 | var ev_consumed = false; | 1346 | var ev_consumed = false; |
| 1304 | defer if (!ev_consumed) await ev; | 1347 | defer if (!ev_consumed) await ev; |
| 1305 | | 1348 | |
| 1306 | // overwrite line 2 | 1349 | // overwrite line 2 |
| 1307 | const fd = try await try async openReadWrite(loop, file_path, File.default_mode); | 1350 | const fd = try await openReadWrite(loop, file_path, File.default_mode); |
| 1308 | { | 1351 | { |
| 1309 | defer os.close(fd); | 1352 | defer os.close(fd); |
| 1310 | | 1353 | |
| 1311 | try await try async pwritev(loop, fd, []const []const u8{"lorem ipsum"}, line2_offset); | 1354 | try pwritev(loop, fd, []const []const u8{"lorem ipsum"}, line2_offset); |
| 1312 | } | 1355 | } |
| 1313 | | 1356 | |
| 1314 | ev_consumed = true; | 1357 | ev_consumed = true; |
| ... | @@ -1316,7 +1359,7 @@ async fn testFsWatch(loop: *Loop) !void { | ... | @@ -1316,7 +1359,7 @@ async fn testFsWatch(loop: *Loop) !void { |
| 1316 | WatchEventId.CloseWrite => {}, | 1359 | WatchEventId.CloseWrite => {}, |
| 1317 | WatchEventId.Delete => @panic("wrong event"), | 1360 | WatchEventId.Delete => @panic("wrong event"), |
| 1318 | } | 1361 | } |
| 1319 | const contents_updated = try await try async readFile(loop, file_path, 1024 * 1024); | 1362 | const contents_updated = try readFile(loop, file_path, 1024 * 1024); |
| 1320 | testing.expectEqualSlices(u8, | 1363 | testing.expectEqualSlices(u8, |
| 1321 | \\line 1 | 1364 | \\line 1 |
| 1322 | \\lorem ipsum | 1365 | \\lorem ipsum |