Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite5d9dc1

Browse files
authored
fix: fix Downloader to dispose tempFile and use synchronous IO (#81)
Fixescoder/internal#598There is a possible race where if the cancellation token is expired, `Download()` never gets called and the tempFile is never disposed of (at least until GC). We also switch to synchronous IO so that a pending overlapped write won't block the deletion.These issues can cause races in our tests when we try to clean up the directory.
1 parent75cdfd0 commite5d9dc1

File tree

2 files changed

+23
-20
lines changed

2 files changed

+23
-20
lines changed

‎Tests.Vpn.Service/DownloaderTest.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -442,23 +442,28 @@ public async Task CancelledWaitingForOther(CancellationToken ct)
442442
[CancelAfter(30_000)]
443443
publicasyncTaskCancelledInner(CancellationTokenct)
444444
{
445+
varhttpCts=CancellationTokenSource.CreateLinkedTokenSource(ct);
446+
vartaskCts=CancellationTokenSource.CreateLinkedTokenSource(ct);
445447
usingvarhttpServer=newTestHttpServer(async ctx=>
446448
{
447449
ctx.Response.StatusCode=200;
448-
awaitctx.Response.OutputStream.WriteAsync("test"u8.ToArray(),ct);
449-
awaitctx.Response.OutputStream.FlushAsync(ct);
450-
awaitTask.Delay(TimeSpan.FromSeconds(5),ct);
450+
awaitctx.Response.OutputStream.WriteAsync("test"u8.ToArray(),httpCts.Token);
451+
awaitctx.Response.OutputStream.FlushAsync(httpCts.Token);
452+
// wait up to 5 seconds.
453+
awaitTask.Delay(TimeSpan.FromSeconds(5),httpCts.Token);
451454
});
452455
varurl=newUri(httpServer.BaseUrl+"/test");
453456
vardestPath=Path.Combine(_tempDir,"test");
454457

455458
varmanager=newDownloader(NullLogger<Downloader>.Instance);
456459
// The "inner" Task should fail.
457-
varsmallerCt=newCancellationTokenSource(TimeSpan.FromSeconds(1)).Token;
460+
vartaskCt=taskCts.Token;
458461
vardlTask=awaitmanager.StartDownloadAsync(newHttpRequestMessage(HttpMethod.Get,url),destPath,
459-
NullDownloadValidator.Instance,smallerCt);
462+
NullDownloadValidator.Instance,taskCt);
463+
awaittaskCts.CancelAsync();
460464
varex=Assert.ThrowsAsync<TaskCanceledException>(async()=>awaitdlTask.Task);
461-
Assert.That(ex.CancellationToken,Is.EqualTo(smallerCt));
465+
Assert.That(ex.CancellationToken,Is.EqualTo(taskCt));
466+
awaithttpCts.CancelAsync();
462467
}
463468

464469
[Test(Description="Validation failure")]

‎Vpn.Service/Downloader.cs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -453,27 +453,25 @@ private async Task Start(CancellationToken ct = default)
453453
if(res.Content.Headers.ContentLength>=0)
454454
TotalBytes=(ulong)res.Content.Headers.ContentLength;
455455

456-
FileStreamtempFile;
457-
try
458-
{
459-
tempFile=File.Create(TempDestinationPath,BufferSize,
460-
FileOptions.Asynchronous|FileOptions.SequentialScan);
461-
}
462-
catch(Exceptione)
463-
{
464-
_logger.LogError(e,"Failed to create temporary file '{TempDestinationPath}'",TempDestinationPath);
465-
throw;
466-
}
467-
468-
awaitDownload(res,tempFile,ct);
456+
awaitDownload(res,ct);
469457
return;
470458
}
471459

472-
privateasyncTaskDownload(HttpResponseMessageres,FileStreamtempFile,CancellationTokenct)
460+
privateasyncTaskDownload(HttpResponseMessageres,CancellationTokenct)
473461
{
474462
try
475463
{
476464
varsha1=res.Headers.Contains("ETag")?SHA1.Create():null;
465+
FileStreamtempFile;
466+
try
467+
{
468+
tempFile=File.Create(TempDestinationPath,BufferSize,FileOptions.SequentialScan);
469+
}
470+
catch(Exceptione)
471+
{
472+
_logger.LogError(e,"Failed to create temporary file '{TempDestinationPath}'",TempDestinationPath);
473+
throw;
474+
}
477475
awaitusing(tempFile)
478476
{
479477
varstream=awaitres.Content.ReadAsStreamAsync(ct);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp