-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FileStream.Unix: improve DeleteOnClose when FileShare.None. (#55327)
* FileStream.Unix: improve DeleteOnClose when FileShare.None. Use FileShare.None lock to detect when another Handle that has DeleteOnClose deleted the file, and then re-open it. * Rephrase comment * FileStream_DeleteOnClose: handle a few special cases. * Try avoiding test timeout on arm * Limit check to filemodes that open an existing file, or create it when it doesn't exist. * PR feedback * Limit functional change to FileMode.OpenOrCreate, and increase test timeout. * Fix comment. Co-authored-by: Carlos Sanchez <1175054+carlossanlop@users.noreply.github.com> Co-authored-by: Carlos Sanchez <1175054+carlossanlop@users.noreply.github.com>
- Loading branch information
1 parent
ec15b53
commit 25d4999
Showing
3 changed files
with
190 additions
and
46 deletions.
There are no files selected for viewing
81 changes: 81 additions & 0 deletions
81
src/libraries/System.IO.FileSystem/tests/FileStream/DeleteOnClose.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Xunit; | ||
|
||
namespace System.IO.Tests | ||
{ | ||
public class FileStream_DeleteOnClose : FileSystemTest | ||
{ | ||
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsFileLockingEnabled), nameof(PlatformDetection.IsThreadingSupported))] | ||
public async Task OpenOrCreate_DeleteOnClose_UsableAsMutex() | ||
{ | ||
var cts = new CancellationTokenSource(); | ||
int enterCount = 0; | ||
int locksRemaining = int.MaxValue; | ||
bool exclusive = true; | ||
|
||
string path = GetTestFilePath(); | ||
Assert.False(File.Exists(path)); | ||
|
||
Func<Task> lockFile = async () => | ||
{ | ||
while (!cts.IsCancellationRequested) | ||
{ | ||
try | ||
{ | ||
using (var fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, 4096, FileOptions.DeleteOnClose)) | ||
{ | ||
int counter = Interlocked.Increment(ref enterCount); | ||
if (counter != 1) | ||
{ | ||
// Test failed. | ||
exclusive = false; | ||
cts.Cancel(); // Stop other Tasks. | ||
return; | ||
} | ||
// Hold the lock for a little bit. | ||
await Task.Delay(TimeSpan.FromMilliseconds(5)); | ||
Interlocked.Decrement(ref enterCount); | ||
if (Interlocked.Decrement(ref locksRemaining) <= 0) | ||
{ | ||
return; | ||
} | ||
} | ||
await Task.Delay(TimeSpan.FromMilliseconds(1)); | ||
} | ||
catch (UnauthorizedAccessException) | ||
{ | ||
// This can occur when the file is being deleted on Windows. | ||
await Task.Delay(TimeSpan.FromMilliseconds(1)); | ||
} | ||
catch (IOException) | ||
{ | ||
// The file is opened by another Task. | ||
await Task.Delay(TimeSpan.FromMilliseconds(1)); | ||
} | ||
} | ||
}; | ||
|
||
var tasks = new Task[50]; | ||
for (int i = 0; i < tasks.Length; i++) | ||
{ | ||
tasks[i] = Task.Run(lockFile); | ||
} | ||
|
||
// Wait for 1000 locks. | ||
cts.CancelAfter(TimeSpan.FromSeconds(60)); // Test timeout. | ||
Volatile.Write(ref locksRemaining, 500); | ||
await Task.WhenAll(tasks); | ||
|
||
Assert.True(exclusive, "Exclusive"); | ||
Assert.False(cts.IsCancellationRequested, "Test cancelled"); | ||
Assert.False(File.Exists(path), "File exists"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters