Skip to content

Commit 7348c6c

Browse files
authored
Fix File.flush return value for case of zero bytes to flush. (#2704)
1 parent a83375f commit 7348c6c

File tree

2 files changed

+43
-17
lines changed

2 files changed

+43
-17
lines changed

packages/files/_test.pony

+29
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ actor Main is TestList
3939
test(_TestFileQueuev)
4040
test(_TestFileMixedWriteQueue)
4141
test(_TestFileWritevLarge)
42+
test(_TestFileFlush)
4243

4344
primitive _FileHelper
4445
fun make_files(h: TestHelper, files: Array[String]): FilePath ? =>
@@ -775,3 +776,31 @@ class iso _TestFileWritevLarge is UnitTest
775776
else
776777
h.fail("Unhandled error!")
777778
end
779+
780+
class iso _TestFileFlush is UnitTest
781+
fun name(): String => "files/File.flush"
782+
fun apply(h: TestHelper) =>
783+
try
784+
let path = FilePath(h.env.root as AmbientAuth, "tmp.flush")?
785+
with file = CreateFile(path) as File do
786+
// Flush with no writes succeeds trivially, but does nothing.
787+
h.assert_true(file.flush())
788+
789+
file.queue("foobar\n")
790+
791+
// Without flushing, the file size is still zero.
792+
with read_file = CreateFile(path) as File do
793+
h.assert_eq[USize](0, read_file.size())
794+
end
795+
796+
h.assert_true(file.flush())
797+
798+
// Now expect to be able to see the data.
799+
with read_file = CreateFile(path) as File do
800+
h.assert_eq[String]("foobar", read_file.line()?)
801+
end
802+
end
803+
path.remove()
804+
else
805+
h.fail("Unhandled error!")
806+
end

packages/files/file.pony

+14-17
Original file line numberDiff line numberDiff line change
@@ -461,19 +461,22 @@ class File
461461
"""
462462
Write pending data.
463463
Returns false if the file wasn't opened with write permission.
464-
Returns raises error if not all the bytes were written.
464+
Raises an error if not all the bytes were written.
465465
Returns true if it sent all pending data.
466466
Returns num_processed and new pending_total also.
467467
"""
468-
// TODO: Make writev_batch_size user configurable
469-
let writev_batch_size = @pony_os_writev_max()
470468
var num_to_send: I32 = 0
471469
var num_sent: USize = 0
472470
var bytes_to_send: USize = 0
473471
var pending_total = _pending_writev_total
474-
while
475-
writeable and (pending_total > 0) and (_fd != -1)
476-
do
472+
473+
if (not writeable) or (_fd == -1) then
474+
return (false, num_sent, pending_total)
475+
end
476+
477+
// TODO: Make writev_batch_size user configurable
478+
let writev_batch_size = @pony_os_writev_max()
479+
while pending_total > 0 do
477480
//determine number of bytes and buffers to send
478481
if (_pending_writev.size().i32()/2) < writev_batch_size then
479482
num_to_send = _pending_writev.size().i32()/2
@@ -500,20 +503,14 @@ class File
500503
num_to_send).isize()
501504
end
502505

503-
if len < bytes_to_send.isize() then
504-
error
505-
else
506-
// sent all data we requested in this batch
507-
pending_total = pending_total - bytes_to_send
508-
num_sent = num_sent + num_to_send.usize()
506+
if len < bytes_to_send.isize() then error end
509507

510-
if pending_total == 0 then
511-
return (true, num_sent, pending_total)
512-
end
513-
end
508+
// sent all data we requested in this batch
509+
pending_total = pending_total - bytes_to_send
510+
num_sent = num_sent + num_to_send.usize()
514511
end
515512

516-
(false, num_sent, pending_total)
513+
(true, num_sent, pending_total)
517514

518515
fun ref position(): USize =>
519516
"""

0 commit comments

Comments
 (0)