Skip to content

Commit

Permalink
Fix File.writev and File.flush in cases where the IO vector exceeds I…
Browse files Browse the repository at this point in the history
…OV_MAX.
  • Loading branch information
jemc authored and SeanTAllen committed Jun 9, 2018
1 parent e193c42 commit 2ae305d
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 12 deletions.
8 changes: 6 additions & 2 deletions packages/files/_test.pony
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ class iso _TestFileWritev is UnitTest
let path = "tmp.writev"
let filepath = FilePath(h.env.root as AmbientAuth, path)?
with file = CreateFile(filepath) as File do
file.writev(wb.done())
h.assert_true(file.writev(wb.done()))
end
with file2 = CreateFile(filepath) as File do
let fileline1 = file2.line()?
Expand Down Expand Up @@ -765,14 +765,18 @@ class iso _TestFileWritevLarge is UnitTest
let path = "tmp.writevlarge"
let filepath = FilePath(h.env.root as AmbientAuth, path)?
with file = CreateFile(filepath) as File do
file.writev(wb.done())
h.assert_true(file.writev(wb.done()))
end
with file2 = CreateFile(filepath) as File do
count = 0
while count < writev_batch_size do
let fileline1 = file2.line()?
h.assert_eq[String](count.string(), consume fileline1)
count = count + 1
h.log(count.string())
end
try
h.fail("expected end of file, but got line: " + file2.line()?)
end
end
filepath.remove()
Expand Down
20 changes: 10 additions & 10 deletions packages/files/file.pony
Original file line number Diff line number Diff line change
Expand Up @@ -477,35 +477,35 @@ class File
// TODO: Make writev_batch_size user configurable
let writev_batch_size = @pony_os_writev_max()
while pending_total > 0 do
//determine number of bytes and buffers to send
if (_pending_writev.size().i32()/2) < writev_batch_size then
num_to_send = _pending_writev.size().i32()/2
// Determine the number of bytes and buffers to send.
num_to_send = (_pending_writev.size().i32() / 2) - num_sent.i32()
if num_to_send <= writev_batch_size then
bytes_to_send = pending_total
else
//have more buffers than a single writev can handle
//iterate over buffers being sent to add up total
// We have more buffers than a single writev can handle.
// We must iterate over the buffers being sent to add up to the total.
num_to_send = writev_batch_size
bytes_to_send = 0
var counter: I32 = (num_sent.i32()*2) + 1
var counter: I32 = (num_sent.i32() * 2) + 1
repeat
bytes_to_send = bytes_to_send + _pending_writev(counter.usize())?
counter = counter + 2
until counter >= (num_to_send*2) end
until counter >= (num_to_send * 2) end
end

// Write as much data as possible (vectored i/o).
// On Windows only write 1 buffer at a time.
var len = ifdef windows then
@_write(_fd, _pending_writev(num_sent*2)?,
@_write(_fd, _pending_writev(num_sent * 2)?,
bytes_to_send.i32()).isize()
else
@writev(_fd, _pending_writev.cpointer(num_sent*2),
@writev(_fd, _pending_writev.cpointer(num_sent * 2),
num_to_send).isize()
end

if len < bytes_to_send.isize() then error end

// sent all data we requested in this batch
// We've sent all the data we requested in this batch.
pending_total = pending_total - bytes_to_send
num_sent = num_sent + num_to_send.usize()
end
Expand Down

0 comments on commit 2ae305d

Please sign in to comment.