CompareExchangeCurrentOverlappedOwner() private method

private CompareExchangeCurrentOverlappedOwner ( FileStreamCompletionSource newSource, FileStreamCompletionSource existingSource ) : FileStreamCompletionSource
newSource FileStreamCompletionSource
existingSource FileStreamCompletionSource
return FileStreamCompletionSource
            internal virtual void ReleaseNativeResource()
            {
                // Ensure that cancellation has been completed and cleaned up.
                _cancellationRegistration.Dispose();

                // Free the overlapped.
                // NOTE: The cancellation must *NOT* be running at this point, or it may observe freed memory
                // (this is why we disposed the registration above).
                if (_overlapped != null)
                {
                    _stream._fileHandle.ThreadPoolBinding !.FreeNativeOverlapped(_overlapped);
                    _overlapped = null;
                }

                // Ensure we're no longer set as the current completion source (we may not have been to begin with).
                // Only one operation at a time is eligible to use the preallocated overlapped,
                _stream.CompareExchangeCurrentOverlappedOwner(null, this);
            }
Example #2
0
            private long _result;                  // Using long since this needs to be used in Interlocked APIs

            // Using RunContinuationsAsynchronously for compat reasons (old API used Task.Factory.StartNew for continuations)
            internal FileStreamCompletionSource(FileStream stream, int numBufferedBytes, byte[] bytes, CancellationToken cancellationToken)
                : base(TaskCreationOptions.RunContinuationsAsynchronously)
            {
                _numBufferedBytes  = numBufferedBytes;
                _stream            = stream;
                _result            = NoResult;
                _cancellationToken = cancellationToken;

                // Create the native overlapped. We try to use the preallocated overlapped if possible:
                // it's possible if the byte buffer is the same one that's associated with the preallocated overlapped
                // and if no one else is currently using the preallocated overlapped.  This is the fast-path for cases
                // where the user-provided buffer is smaller than the FileStream's buffer (such that the FileStream's
                // buffer is used) and where operations on the FileStream are not being performed concurrently.
                _overlapped = ReferenceEquals(bytes, _stream._buffer) && _stream.CompareExchangeCurrentOverlappedOwner(this, null) == null?
                              _stream._fileHandle.ThreadPoolBinding.AllocateNativeOverlapped(_stream._preallocatedOverlapped) :
                                  _stream._fileHandle.ThreadPoolBinding.AllocateNativeOverlapped(s_ioCallback, this, bytes);

                Debug.Assert(_overlapped != null, "AllocateNativeOverlapped returned null");
            }
            private long _result;                  // Using long since this needs to be used in Interlocked APIs

            // Using RunContinuationsAsynchronously for compat reasons (old API used Task.Factory.StartNew for continuations)
            protected FileStreamCompletionSource(FileStream stream, int numBufferedBytes, byte[]?bytes)
                : base(TaskCreationOptions.RunContinuationsAsynchronously)
            {
                _numBufferedBytes = numBufferedBytes;
                _stream           = stream;
                _result           = NoResult;

                // Create the native overlapped. We try to use the preallocated overlapped if possible: it's possible if the byte
                // buffer is null (there's nothing to pin) or the same one that's associated with the preallocated overlapped (and
                // thus is already pinned) and if no one else is currently using the preallocated overlapped.  This is the fast-path
                // for cases where the user-provided buffer is smaller than the FileStream's buffer (such that the FileStream's
                // buffer is used) and where operations on the FileStream are not being performed concurrently.
                Debug.Assert(bytes == null || ReferenceEquals(bytes, _stream._buffer));

                // The _preallocatedOverlapped is null if the internal buffer was never created, so we check for
                // a non-null bytes before using the stream's _preallocatedOverlapped
                _overlapped = bytes != null && _stream.CompareExchangeCurrentOverlappedOwner(this, null) == null ?
                              _stream._fileHandle.ThreadPoolBinding !.AllocateNativeOverlapped(_stream._preallocatedOverlapped !) : // allocated when buffer was created, and buffer is non-null
                              _stream._fileHandle.ThreadPoolBinding !.AllocateNativeOverlapped(s_ioCallback, this, bytes);
                Debug.Assert(_overlapped != null, "AllocateNativeOverlapped returned null");
            }