Skip to content

Commit

Permalink
Rename SafeFileHandle.ValueTaskSource to OverlappedValueTaskSource.
Browse files Browse the repository at this point in the history
  • Loading branch information
teo-tsirpanis committed Jul 3, 2021
1 parent 218b566 commit 58af87c
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,34 @@ namespace Microsoft.Win32.SafeHandles
{
public sealed partial class SafeFileHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private ValueTaskSource? _reusableValueTaskSource; // reusable ValueTaskSource that is currently NOT being used
private OverlappedValueTaskSource? _reusableOverlappedValueTaskSource; // reusable OverlappedValueTaskSource that is currently NOT being used

// Rent the reusable ValueTaskSource, or create a new one to use if we couldn't get one (which
// should only happen on first use or if the FileStream is being used concurrently).
internal ValueTaskSource GetValueTaskSource() => Interlocked.Exchange(ref _reusableValueTaskSource, null) ?? new ValueTaskSource(this);
// Rent the reusable OverlappedValueTaskSource, or create a new one to use if we couldn't get one (which
// should only happen on first use or if the SafeFileHandle is being used concurrently).
internal OverlappedValueTaskSource GetOverlappedValueTaskSource() =>
Interlocked.Exchange(ref _reusableOverlappedValueTaskSource, null) ?? new OverlappedValueTaskSource(this);

protected override bool ReleaseHandle()
{
bool result = Interop.Kernel32.CloseHandle(handle);

Interlocked.Exchange(ref _reusableValueTaskSource, null)?.Dispose();
Interlocked.Exchange(ref _reusableOverlappedValueTaskSource, null)?.Dispose();

return result;
}

private void TryToReuse(ValueTaskSource source)
private void TryToReuse(OverlappedValueTaskSource source)
{
source._source.Reset();

if (Interlocked.CompareExchange(ref _reusableValueTaskSource, source, null) is not null)
if (Interlocked.CompareExchange(ref _reusableOverlappedValueTaskSource, source, null) is not null)
{
source._preallocatedOverlapped.Dispose();
}
}

/// <summary>Reusable IValueTaskSource for FileStream ValueTask-returning async operations.</summary>
internal sealed unsafe class ValueTaskSource : IValueTaskSource<int>, IValueTaskSource
/// <summary>Reusable IValueTaskSource for RandomAccess async operations based on Overlapped I/O.</summary>
internal sealed unsafe class OverlappedValueTaskSource : IValueTaskSource<int>, IValueTaskSource
{
internal static readonly IOCompletionCallback s_ioCallback = IOCallback;

Expand All @@ -55,7 +56,7 @@ internal sealed unsafe class ValueTaskSource : IValueTaskSource<int>, IValueTask
/// </summary>
internal ulong _result;

internal ValueTaskSource(SafeFileHandle fileHandle)
internal OverlappedValueTaskSource(SafeFileHandle fileHandle)
{
_fileHandle = fileHandle;
_source.RunContinuationsAsynchronously = true;
Expand Down Expand Up @@ -112,7 +113,7 @@ internal void RegisterForCancellation(CancellationToken cancellationToken)
{
_cancellationRegistration = cancellationToken.UnsafeRegister(static (s, token) =>
{
ValueTaskSource vts = (ValueTaskSource)s!;
OverlappedValueTaskSource vts = (OverlappedValueTaskSource)s!;
if (!vts._fileHandle.IsInvalid)
{
try
Expand Down Expand Up @@ -156,7 +157,7 @@ internal void ReleaseResources()
// done by that cancellation registration, e.g. unregistering. As such, we use _result to both track who's
// responsible for calling Complete and for passing the necessary data between parties.

/// <summary>Invoked when AsyncWindowsFileStreamStrategy has finished scheduling the async operation.</summary>
/// <summary>Invoked when the async operation finished being scheduled.</summary>
internal void FinishedScheduling()
{
// Set the value to 1. If it was already non-0, then the asynchronous operation already completed but
Expand All @@ -172,7 +173,7 @@ internal void FinishedScheduling()
/// <summary>Invoked when the asynchronous operation has completed asynchronously.</summary>
private static void IOCallback(uint errorCode, uint numBytes, NativeOverlapped* pOverlapped)
{
ValueTaskSource? vts = (ValueTaskSource?)ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped);
OverlappedValueTaskSource? vts = (OverlappedValueTaskSource?)ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped);
Debug.Assert(vts is not null);
Debug.Assert(vts._overlapped == pOverlapped, "Overlaps don't match");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1777,7 +1777,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Internal\Console.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Internal\Win32\RegistryKey.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeFileHandle.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeFileHandle.ValueTaskSource.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeFileHandle.OverlappedValueTaskSource.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeFindHandle.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeRegistryHandle.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeRegistryHandle.Windows.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,17 +213,17 @@ private static ValueTask<int> ReadAtOffsetAsync(SafeFileHandle handle, Memory<by
? Map(QueueAsyncReadFile(handle, buffer, fileOffset, cancellationToken))
: ScheduleSyncReadAtOffsetAsync(handle, buffer, fileOffset, cancellationToken);

private static ValueTask<int> Map((SafeFileHandle.ValueTaskSource? vts, int errorCode) tuple)
private static ValueTask<int> Map((SafeFileHandle.OverlappedValueTaskSource? vts, int errorCode) tuple)
=> tuple.vts != null
? new ValueTask<int>(tuple.vts, tuple.vts.Version)
: tuple.errorCode == 0 ? ValueTask.FromResult(0) : ValueTask.FromException<int>(Win32Marshal.GetExceptionForWin32Error(tuple.errorCode));

internal static unsafe (SafeFileHandle.ValueTaskSource? vts, int errorCode) QueueAsyncReadFile(
internal static unsafe (SafeFileHandle.OverlappedValueTaskSource? vts, int errorCode) QueueAsyncReadFile(
SafeFileHandle handle, Memory<byte> buffer, long fileOffset, CancellationToken cancellationToken)
{
handle.EnsureThreadPoolBindingInitialized();

SafeFileHandle.ValueTaskSource vts = handle.GetValueTaskSource();
SafeFileHandle.OverlappedValueTaskSource vts = handle.GetOverlappedValueTaskSource();
try
{
NativeOverlapped* nativeOverlapped = vts.PrepareForOperation(buffer, fileOffset);
Expand Down Expand Up @@ -274,12 +274,12 @@ private static ValueTask<int> WriteAtOffsetAsync(SafeFileHandle handle, ReadOnly
? Map(QueueAsyncWriteFile(handle, buffer, fileOffset, cancellationToken))
: ScheduleSyncWriteAtOffsetAsync(handle, buffer, fileOffset, cancellationToken);

internal static unsafe (SafeFileHandle.ValueTaskSource? vts, int errorCode) QueueAsyncWriteFile(
internal static unsafe (SafeFileHandle.OverlappedValueTaskSource? vts, int errorCode) QueueAsyncWriteFile(
SafeFileHandle handle, ReadOnlyMemory<byte> buffer, long fileOffset, CancellationToken cancellationToken)
{
handle.EnsureThreadPoolBindingInitialized();

SafeFileHandle.ValueTaskSource vts = handle.GetValueTaskSource();
SafeFileHandle.OverlappedValueTaskSource vts = handle.GetOverlappedValueTaskSource();
try
{
NativeOverlapped* nativeOverlapped = vts.PrepareForOperation(buffer, fileOffset);
Expand Down Expand Up @@ -439,7 +439,7 @@ private static unsafe ValueTask<int> ReadFileScatterAsync(SafeFileHandle handle,
{
handle.EnsureThreadPoolBindingInitialized();

SafeFileHandle.ValueTaskSource vts = handle.GetValueTaskSource();
SafeFileHandle.OverlappedValueTaskSource vts = handle.GetOverlappedValueTaskSource();
try
{
NativeOverlapped* nativeOverlapped = vts.PrepareForOperation(Memory<byte>.Empty, fileOffset);
Expand Down Expand Up @@ -595,7 +595,7 @@ private static unsafe ValueTask<int> WriteFileGatherAsync(SafeFileHandle handle,
{
handle.EnsureThreadPoolBindingInitialized();

SafeFileHandle.ValueTaskSource vts = handle.GetValueTaskSource();
SafeFileHandle.OverlappedValueTaskSource vts = handle.GetOverlappedValueTaskSource();
try
{
NativeOverlapped* nativeOverlapped = vts.PrepareForOperation(ReadOnlyMemory<byte>.Empty, fileOffset);
Expand All @@ -618,7 +618,7 @@ private static unsafe ValueTask<int> WriteFileGatherAsync(SafeFileHandle handle,
vts.Dispose();
return errorCode == Interop.Errors.ERROR_NO_DATA // EOF on a pipe. IO callback will not be called.
? ValueTask.FromResult<int>(0)
: ValueTask.FromException<int>(SafeFileHandle.ValueTaskSource.GetIOError(errorCode, path: null));
: ValueTask.FromException<int>(SafeFileHandle.OverlappedValueTaskSource.GetIOError(errorCode, path: null));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ private unsafe ValueTask<int> ReadAsyncInternal(Memory<byte> destination, Cancel
_filePosition += destination.Length;
}

(SafeFileHandle.ValueTaskSource? vts, int errorCode) = RandomAccess.QueueAsyncReadFile(_fileHandle, destination, positionBefore, cancellationToken);
(SafeFileHandle.OverlappedValueTaskSource? vts, int errorCode) = RandomAccess.QueueAsyncReadFile(_fileHandle, destination, positionBefore, cancellationToken);
return vts != null
? new ValueTask<int>(vts, vts.Version)
: (errorCode == 0) ? ValueTask.FromResult(0) : ValueTask.FromException<int>(HandleIOError(positionBefore, errorCode));
Expand Down Expand Up @@ -81,7 +81,7 @@ private unsafe ValueTask WriteAsyncInternal(ReadOnlyMemory<byte> source, Cancell
UpdateLengthOnChangePosition();
}

(SafeFileHandle.ValueTaskSource? vts, int errorCode) = RandomAccess.QueueAsyncWriteFile(_fileHandle, source, positionBefore, cancellationToken);
(SafeFileHandle.OverlappedValueTaskSource? vts, int errorCode) = RandomAccess.QueueAsyncWriteFile(_fileHandle, source, positionBefore, cancellationToken);
return vts != null
? new ValueTask(vts, vts.Version)
: (errorCode == 0) ? ValueTask.CompletedTask : ValueTask.FromException(HandleIOError(positionBefore, errorCode));
Expand All @@ -95,7 +95,7 @@ private Exception HandleIOError(long positionBefore, int errorCode)
_filePosition = positionBefore;
}

return SafeFileHandle.ValueTaskSource.GetIOError(errorCode, _path);
return SafeFileHandle.OverlappedValueTaskSource.GetIOError(errorCode, _path);
}

public override Task FlushAsync(CancellationToken cancellationToken) => Task.CompletedTask; // no buffering = nothing to flush
Expand Down

0 comments on commit 58af87c

Please sign in to comment.