Skip to content

Commit

Permalink
Fixed false download cancellation and a race condition
Browse files Browse the repository at this point in the history
  • Loading branch information
Nuclearistt committed Mar 12, 2024
1 parent f06c07a commit a0b8ea5
Showing 1 changed file with 13 additions and 18 deletions.
31 changes: 13 additions & 18 deletions src/CDNClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,21 +100,11 @@ private static void DownloadThreadProcedure(object? arg)
int bytesRead;
using var cts = CancellationTokenSource.CreateLinkedTokenSource(token);
cts.CancelAfter(60000);
try
{
var task = stream.ReadAtLeastAsync(downloadBuffer, compressedSize, false, cts.Token);
if (task.IsCompletedSuccessfully)
bytesRead = task.GetAwaiter().GetResult();
else
bytesRead = task.AsTask().GetAwaiter().GetResult();
}
catch (OperationCanceledException oce)
{
if (oce.CancellationToken == token)
return;
exception = new TimeoutException();
continue;
}
var task = stream.ReadAtLeastAsync(downloadBuffer, compressedSize, false, cts.Token);
if (task.IsCompletedSuccessfully)
bytesRead = task.GetAwaiter().GetResult();
else
bytesRead = task.AsTask().GetAwaiter().GetResult();
if (bytesRead != compressedSize)
{
exception = new InvalidDataException($"Downloaded chunk data size doesn't match expected [URL: {httpClient.BaseAddress}/{request.RequestUri}]");
Expand All @@ -136,7 +126,12 @@ private static void DownloadThreadProcedure(object? arg)
}
exception = null;
}
catch (OperationCanceledException) { return; }
catch (OperationCanceledException oce)
{
if (oce.CancellationToken == token)
return;
exception = oce;
}
catch (HttpRequestException hre) when (hre.StatusCode > HttpStatusCode.InternalServerError)
{
if (fallbackServerIndex is 0)
Expand Down Expand Up @@ -533,13 +528,13 @@ public static ChunkContext LoadFromBuffer(ReadOnlySpan<byte> buffer, ref nint of
private class LimitedUseFileHandle(SafeFileHandle fileHandle, int numChunks)
{
/// <summary>The number of chunks left to be written to the file.</summary>
public int ChunksLeft { get; private set; } = numChunks;
private int _chunksLeft = numChunks;
/// <summary>File handle.</summary>
public SafeFileHandle Handle { get; } = fileHandle;
/// <summary>Decrements the number of chunks left to write and releases the handle if it becomes zero.</summary>
public void Release()
{
if (--ChunksLeft is 0)
if (Interlocked.Decrement(ref _chunksLeft) is 0)
Handle.Dispose();
}
}
Expand Down

0 comments on commit a0b8ea5

Please sign in to comment.