Skip to content

Commit

Permalink
Testing a theory dotnet#2
Browse files Browse the repository at this point in the history
Previous test was successful, but we don't want to call Length at every iteration.  That's both a perf issue and is potentially a race condition if concurrently the size of the file shrinks.
  • Loading branch information
stephentoub committed Sep 11, 2016
1 parent a1f3510 commit bd71bdb
Showing 1 changed file with 13 additions and 24 deletions.
37 changes: 13 additions & 24 deletions src/System.IO.FileSystem/src/System/IO/Win32FileStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1794,23 +1794,6 @@ private async Task AsyncModeCopyToAsync(Stream destination, int bufferSize, Canc

try
{
// Avoid triggering ERROR_HANDLE_EOFs:
// compute the remaining number of bytes in the file.
int toRead = copyBuffer.Length;
if (canSeek)
{
long remaining = Length - readAwaitable._position;
if (remaining < toRead)
{
if (remaining <= 0)
{
break;
}

toRead = (int)remaining;
}
}

bool synchronousSuccess;
int errorCode;
unsafe
Expand All @@ -1826,19 +1809,25 @@ private async Task AsyncModeCopyToAsync(Stream destination, int bufferSize, Canc
}

// Kick off the read.
synchronousSuccess = ReadFileNative(_handle, copyBuffer, 0, toRead, readAwaitable._nativeOverlapped, out errorCode) >= 0;
synchronousSuccess = ReadFileNative(_handle, copyBuffer, 0, copyBuffer.Length, readAwaitable._nativeOverlapped, out errorCode) >= 0;
}

// If the operation did not synchronously succeed, it either failed or initiated the asynchronous operation.
if (!synchronousSuccess)
{
if (errorCode == ERROR_BROKEN_PIPE)
{
readAwaitable.MarkCompleted(); // overlapped callback won't be raised in this one case
}
else if (errorCode != ERROR_IO_PENDING && errorCode != ERROR_HANDLE_EOF)
switch (errorCode)
{
throw Win32Marshal.GetExceptionForWin32Error(errorCode);
case ERROR_BROKEN_PIPE:
case ERROR_HANDLE_EOF:
// We're at or past the end of the file, and the overlapped callback won't be raised in these cases.
readAwaitable.MarkCompleted();
break;
case ERROR_IO_PENDING:
// Async operation in progress.
break;
default:
// Everything else is an error.
throw Win32Marshal.GetExceptionForWin32Error(errorCode);
}
}

Expand Down

0 comments on commit bd71bdb

Please sign in to comment.