예제 #1
0
 public static FileStreamCompletionSource Create(LegacyFileStreamStrategy stream, int numBufferedBytesRead, ReadOnlyMemory <byte> memory)
 {
     // If the memory passed in is the stream's internal buffer, we can use the base FileStreamCompletionSource,
     // which has a PreAllocatedOverlapped with the memory already pinned.  Otherwise, we use the derived
     // 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(MemoryMarshal.TryGetArray(memory, out ArraySegment <byte> buffer) && ReferenceEquals(buffer.Array, stream._buffer) ?
            new FileStreamCompletionSource(stream, numBufferedBytesRead, buffer.Array) :
            new MemoryFileStreamCompletionSource(stream, numBufferedBytesRead, memory));
 }
예제 #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)
            protected FileStreamCompletionSource(LegacyFileStreamStrategy 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");
            }
예제 #3
0
            private MemoryHandle _handle; // mutable struct; do not make this readonly

            internal MemoryFileStreamCompletionSource(LegacyFileStreamStrategy stream, int numBufferedBytes, ReadOnlyMemory <byte> memory) :
                base(stream, numBufferedBytes, bytes: null) // this type handles the pinning, so null is passed for bytes
            {
                _handle = memory.Pin();
            }