Skip to content

Commit 32fadf9

Browse files
committed
Fix File.flush return value for case of zero bytes to flush.
1 parent a83375f commit 32fadf9

File tree

2 files changed

+51
-17
lines changed

2 files changed

+51
-17
lines changed

packages/files/_test.pony

+37
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,39 @@ 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+
783+
fun tag _expect_file_size(
784+
h: TestHelper,
785+
path: FilePath,
786+
size: USize,
787+
loc: SourceLoc = __loc)
788+
?
789+
=>
790+
with file = CreateFile(path) as File do
791+
h.assert_eq[USize](size, file.size() where loc = loc)
792+
end
793+
794+
fun apply(h: TestHelper) =>
795+
try
796+
let path = FilePath(h.env.root as AmbientAuth, "tmp.flush")?
797+
with file = CreateFile(path) as File do
798+
// Flush with no writes succeeds trivially, but does nothing.
799+
h.assert_true(file.flush())
800+
801+
file.queue("foobar\n")
802+
803+
// Without flushing, the file size is still zero.
804+
_expect_file_size(h, path, 0)?
805+
806+
h.assert_true(file.flush())
807+
808+
// Now expect to see the correct file size.
809+
_expect_file_size(h, path, 7)?
810+
end
811+
path.remove()
812+
else
813+
h.fail("Unhandled error!")
814+
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)