version & 0xFF);
}
- private static readonly Lazy<bool> _legacyFileStream = new Lazy<bool>(() => GetStaticNonPublicBooleanPropertyValue("System.IO.FileStreamHelpers", "UseLegacyStrategy"));
+ private static readonly Lazy<bool> _net5CompatFileStream = new Lazy<bool>(() => GetStaticNonPublicBooleanPropertyValue("System.IO.FileStreamHelpers", "UseNet5CompatStrategy"));
- public static bool IsLegacyFileStreamEnabled => _legacyFileStream.Value;
+ public static bool IsNet5CompatFileStreamEnabled => _net5CompatFileStream.Value;
private static bool GetIsInContainer()
{
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D9FB1730-B750-4C0D-8D24-8C992DEB6034}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.IO.FileSystem.Legacy.Tests", "tests\LegacyTests\System.IO.FileSystem.Legacy.Tests.csproj", "{48E07F12-8597-40DE-8A37-CCBEB9D54012}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.IO.FileSystem.Net5Compat.Tests", "tests\Net5CompatTests\System.IO.FileSystem.Net5Compat.Tests.csproj", "{48E07F12-8597-40DE-8A37-CCBEB9D54012}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StreamConformanceTests", "..\Common\tests\StreamConformanceTests\StreamConformanceTests.csproj", "{FEF03BCC-509F-4646-9132-9DE27FA3DA6F}"
EndProject
}
}
- [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsLegacyFileStreamEnabled))]
+ [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNet5CompatFileStreamEnabled))]
public async Task ThrowWhenHandlePositionIsChanged_sync()
{
await ThrowWhenHandlePositionIsChanged(useAsync: false);
}
- [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported), nameof(PlatformDetection.IsLegacyFileStreamEnabled))]
+ [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported), nameof(PlatformDetection.IsNet5CompatFileStreamEnabled))]
public async Task ThrowWhenHandlePositionIsChanged_async()
{
await ThrowWhenHandlePositionIsChanged(useAsync: true);
&& OperatingSystem.IsWindows()
// ReadAsync which in this case (single byte written to buffer) calls FlushAsync is now 100% async
// so it does not complete synchronously anymore
- && PlatformDetection.IsLegacyFileStreamEnabled)
+ && PlatformDetection.IsNet5CompatFileStreamEnabled)
{
Assert.Throws<IOException>(() => FSAssert.CompletesSynchronously(fs.ReadAsync(new byte[1], 0, 1)));
}
// The side effect of this is that the Position of FileStream is not updated until
// the lock is released by a previous operation.
// So now all WriteAsync calls should be awaited before starting another async file operation.
- if (PlatformDetection.IsLegacyFileStreamEnabled)
+ if (PlatformDetection.IsNet5CompatFileStreamEnabled)
{
Assert.Equal((i + 1) * writeSize, fs.Position);
}
namespace System.IO.Tests
{
- public class LegacySwitchTests
+ public class Net5CompatSwitchTests
{
[Fact]
public static void LegacySwitchIsHonored()
.GetField("_strategy", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(fileStream);
- Assert.DoesNotContain(strategy.GetType().FullName, "Legacy");
+ Assert.DoesNotContain("Net5Compat", strategy.GetType().FullName);
}
File.Delete(filePath);
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<IncludeRemoteExecutor>true</IncludeRemoteExecutor>
- <!-- currently we have non Legacy strategy only for Windows, so we run the tests only on Windows -->
+ <!-- Windows is currently the only OS for which we provide a new strategy, so we test the Net5Compat only for Windows -->
<TargetFrameworks>$(NetCoreAppCurrent)-windows</TargetFrameworks>
<RunTestsJSArguments>--working-dir=/test-dir</RunTestsJSArguments>
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D9FD8082-D04C-4DA8-9F4C-261D1C65A6D3}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.IO.Legacy.Tests", "tests\LegacyTests\System.IO.Legacy.Tests.csproj", "{0217540D-FA86-41B3-9754-7BB5096ABA3E}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.IO.Net5Compat.Tests", "tests\Net5CompatTests\System.IO.Net5Compat.Tests.csproj", "{0217540D-FA86-41B3-9754-7BB5096ABA3E}"
EndProject
Global
GlobalSection(NestedProjects) = preSolution
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TestRuntime>true</TestRuntime>
<IncludeRemoteExecutor>true</IncludeRemoteExecutor>
- <!-- currently we have non Legacy strategy only for Windows, so we run the tests only on Windows -->
+ <!-- Windows is currently the only OS for which we provide a new strategy, so we test the Net5Compat only for Windows -->
<TargetFrameworks>$(NetCoreAppCurrent)-windows</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)System\IO\Strategies\DerivedFileStreamStrategy.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\Strategies\FileStreamHelpers.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\Strategies\FileStreamStrategy.cs" />
- <Compile Include="$(MSBuildThisFileDirectory)System\IO\Strategies\LegacyFileStreamStrategy.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\Strategies\Net5CompatFileStreamStrategy.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IObservable.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IObserver.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IProgress.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\Strategies\AsyncWindowsFileStreamStrategy.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\Strategies\FileStreamHelpers.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\Strategies\FileStreamCompletionSource.Win32.cs" />
- <Compile Include="$(MSBuildThisFileDirectory)System\IO\Strategies\LegacyFileStreamStrategy.Windows.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\Strategies\Net5CompatFileStreamStrategy.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\Strategies\SyncWindowsFileStreamStrategy.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\Strategies\WindowsFileStreamStrategy.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\PasteArguments.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\PathInternal.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\PersistedFiles.Names.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\Strategies\FileStreamHelpers.Unix.cs" />
- <Compile Include="$(MSBuildThisFileDirectory)System\IO\Strategies\LegacyFileStreamStrategy.Unix.cs" />
- <Compile Include="$(MSBuildThisFileDirectory)System\IO\Strategies\LegacyFileStreamStrategy.Lock.OSX.cs" Condition="'$(IsOSXLike)' == 'true'" />
- <Compile Include="$(MSBuildThisFileDirectory)System\IO\Strategies\LegacyFileStreamStrategy.Lock.Unix.cs" Condition="'$(IsOSXLike)' != 'true'" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\Strategies\Net5CompatFileStreamStrategy.Unix.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\Strategies\Net5CompatFileStreamStrategy.Lock.OSX.cs" Condition="'$(IsOSXLike)' == 'true'" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\Strategies\Net5CompatFileStreamStrategy.Lock.Unix.cs" Condition="'$(IsOSXLike)' != 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\PasteArguments.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Loader\LibraryNameVariation.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\MemoryFailPoint.Unix.cs" />
namespace System.IO.Strategies
{
- // to avoid code duplicaiton of FileStreamCompletionSource for LegacyFileStreamStrategy and AsyncWindowsFileStreamStrategy
+ // to avoid code duplicaiton of FileStreamCompletionSource for Net5CompatFileStreamStrategy and AsyncWindowsFileStreamStrategy
// we have created the following interface that is a common contract for both of them
internal interface IFileStreamCompletionSourceStrategy
{
// MemoryFileStreamCompletionSource, which Retains the memory, which will result in less pinning in the case
// where the underlying memory is backed by pre-pinned buffers.
return preallocatedOverlapped != null && MemoryMarshal.TryGetArray(memory, out ArraySegment<byte> buffer)
- && preallocatedOverlapped.IsUserObject(buffer.Array) // preallocatedOverlapped is allocated when BufferedStream|LegacyFileStreamStrategy allocates the buffer
+ && preallocatedOverlapped.IsUserObject(buffer.Array) // preallocatedOverlapped is allocated when BufferedStream|Net5CompatFileStreamStrategy allocates the buffer
? new FileStreamCompletionSource(strategy, preallocatedOverlapped, numBufferedBytesRead, buffer.Array)
: new MemoryFileStreamCompletionSource(strategy, numBufferedBytesRead, memory);
}
{
// in the future we are most probably going to introduce more strategies (io_uring etc)
private static FileStreamStrategy ChooseStrategyCore(SafeFileHandle handle, FileAccess access, FileShare share, int bufferSize, bool isAsync)
- => new LegacyFileStreamStrategy(handle, access, bufferSize, isAsync);
+ => new Net5CompatFileStreamStrategy(handle, access, bufferSize, isAsync);
private static FileStreamStrategy ChooseStrategyCore(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options)
- => new LegacyFileStreamStrategy(path, mode, access, share, bufferSize, options);
+ => new Net5CompatFileStreamStrategy(path, mode, access, share, bufferSize, options);
internal static SafeFileHandle OpenHandle(string path, FileMode mode, FileAccess access, FileShare share, FileOptions options)
{
private static FileStreamStrategy ChooseStrategyCore(SafeFileHandle handle, FileAccess access, FileShare share, int bufferSize, bool isAsync)
{
- if (UseLegacyStrategy)
+ if (UseNet5CompatStrategy)
{
- return new LegacyFileStreamStrategy(handle, access, bufferSize, isAsync);
+ return new Net5CompatFileStreamStrategy(handle, access, bufferSize, isAsync);
}
WindowsFileStreamStrategy strategy = isAsync
private static FileStreamStrategy ChooseStrategyCore(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options)
{
- if (UseLegacyStrategy)
+ if (UseNet5CompatStrategy)
{
- return new LegacyFileStreamStrategy(path, mode, access, share, bufferSize, options);
+ return new Net5CompatFileStreamStrategy(path, mode, access, share, bufferSize, options);
}
WindowsFileStreamStrategy strategy = (options & FileOptions.Asynchronous) != 0
}
}
- /// <summary>Used by AsyncWindowsFileStreamStrategy and LegacyFileStreamStrategy CopyToAsync to enable awaiting the result of an overlapped I/O operation with minimal overhead.</summary>
+ /// <summary>Used by AsyncWindowsFileStreamStrategy and Net5CompatFileStreamStrategy CopyToAsync to enable awaiting the result of an overlapped I/O operation with minimal overhead.</summary>
private sealed unsafe class AsyncCopyToAwaitable : ICriticalNotifyCompletion
{
/// <summary>Sentinel object used to indicate that the I/O operation has completed before being awaited.</summary>
internal static partial class FileStreamHelpers
{
// It's enabled by default. We are going to change that once we fix #16354, #25905 and #24847.
- internal static bool UseLegacyStrategy { get; } = GetLegacyFileStreamSetting();
+ internal static bool UseNet5CompatStrategy { get; } = GetNet5CompatFileStreamSetting();
- private static bool GetLegacyFileStreamSetting()
+ private static bool GetNet5CompatFileStreamSetting()
{
if (AppContext.TryGetSwitch("System.IO.UseNet5CompatFileStream", out bool fileConfig))
{
string? envVar = Environment.GetEnvironmentVariable("DOTNET_SYSTEM_IO_USENET5COMPATFILESTREAM");
return envVar is null
- ? true // legacy is currently enabled by default;
+ ? true // Net5Compat is currently enabled by default;
: bool.IsTrueStringIgnoreCase(envVar) || envVar.Equals("1");
}
namespace System.IO.Strategies
{
- internal sealed partial class LegacyFileStreamStrategy : FileStreamStrategy
+ internal sealed partial class Net5CompatFileStreamStrategy : FileStreamStrategy
{
internal override void Lock(long position, long length)
{
namespace System.IO.Strategies
{
- internal sealed partial class LegacyFileStreamStrategy : FileStreamStrategy
+ internal sealed partial class Net5CompatFileStreamStrategy : FileStreamStrategy
{
/// <summary>Prevents other processes from reading from or writing to the FileStream.</summary>
/// <param name="position">The beginning of the range to lock.</param>
namespace System.IO.Strategies
{
/// <summary>Provides an implementation of a file stream for Unix files.</summary>
- internal sealed partial class LegacyFileStreamStrategy : FileStreamStrategy
+ internal sealed partial class Net5CompatFileStreamStrategy : FileStreamStrategy
{
/// <summary>File mode.</summary>
private FileMode _mode;
// override may already exist on a derived type.
if (_useAsyncIO && _writePos > 0)
{
- return new ValueTask(Task.Factory.StartNew(static s => ((LegacyFileStreamStrategy)s!).Dispose(), this,
+ return new ValueTask(Task.Factory.StartNew(static s => ((Net5CompatFileStreamStrategy)s!).Dispose(), this,
CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default));
}
// whereas on Windows it may happen before the write has completed.
Debug.Assert(t.Status == TaskStatus.RanToCompletion);
- var thisRef = (LegacyFileStreamStrategy)s!;
+ var thisRef = (Net5CompatFileStreamStrategy)s!;
Debug.Assert(thisRef._asyncState != null);
try
{
// whereas on Windows it may happen before the write has completed.
Debug.Assert(t.Status == TaskStatus.RanToCompletion);
- var thisRef = (LegacyFileStreamStrategy)s!;
+ var thisRef = (Net5CompatFileStreamStrategy)s!;
Debug.Assert(thisRef._asyncState != null);
try
{
namespace System.IO.Strategies
{
- internal sealed partial class LegacyFileStreamStrategy : FileStreamStrategy, IFileStreamCompletionSourceStrategy
+ internal sealed partial class Net5CompatFileStreamStrategy : FileStreamStrategy, IFileStreamCompletionSourceStrategy
{
private bool _canSeek;
private bool _isPipe; // Whether to disable async buffering code.
namespace System.IO.Strategies
{
- // This type is partial so we can avoid code duplication between Windows and Unix Legacy implementations
- internal sealed partial class LegacyFileStreamStrategy : FileStreamStrategy
+ // This type is partial so we can avoid code duplication between Windows and Unix Net5Compat implementations
+ internal sealed partial class Net5CompatFileStreamStrategy : FileStreamStrategy
{
private byte[]? _buffer;
private readonly int _bufferLength;
/// <summary>Whether the file stream's handle has been exposed.</summary>
private bool _exposedHandle;
- internal LegacyFileStreamStrategy(SafeFileHandle handle, FileAccess access, int bufferSize, bool isAsync)
+ internal Net5CompatFileStreamStrategy(SafeFileHandle handle, FileAccess access, int bufferSize, bool isAsync)
{
_exposedHandle = true;
_bufferLength = bufferSize;
_fileHandle = handle;
}
- internal LegacyFileStreamStrategy(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options)
+ internal Net5CompatFileStreamStrategy(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options)
{
string fullPath = Path.GetFullPath(path);
}
}
- ~LegacyFileStreamStrategy() => Dispose(false); // mandatory to Flush the write buffer
+ ~Net5CompatFileStreamStrategy() => Dispose(false); // mandatory to Flush the write buffer
internal override void DisposeInternal(bool disposing) => Dispose(disposing);