Nullable annotate System.IO.Pipes (#31918)
authorEirik Tsarpalis <eirik.tsarpalis@gmail.com>
Mon, 10 Feb 2020 16:30:25 +0000 (16:30 +0000)
committerGitHub <noreply@github.com>
Mon, 10 Feb 2020 16:30:25 +0000 (16:30 +0000)
* annotate System.IO.Pipes

* update Stream override method signatures

22 files changed:
src/libraries/Common/src/Interop/Windows/Kernel32/Interop.CreateNamedPipeClient.cs
src/libraries/Common/src/Interop/Windows/Kernel32/Interop.WaitNamedPipe.cs
src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs
src/libraries/System.IO.Pipes/ref/System.IO.Pipes.csproj
src/libraries/System.IO.Pipes/src/Microsoft/Win32/SafeHandles/SafePipeHandle.Unix.cs
src/libraries/System.IO.Pipes/src/Microsoft/Win32/SafeHandles/SafePipeHandle.cs
src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj
src/libraries/System.IO.Pipes/src/System/IO/Pipes/AnonymousPipeServerStream.Windows.cs
src/libraries/System.IO.Pipes/src/System/IO/Pipes/AnonymousPipeServerStream.cs
src/libraries/System.IO.Pipes/src/System/IO/Pipes/ConnectionCompletionSource.cs
src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Unix.cs
src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Windows.cs
src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs
src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeServerStream.Unix.cs
src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeServerStream.Win32.cs
src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeServerStream.Windows.cs
src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeCompletionSource.cs
src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeSecurity.cs
src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Unix.cs
src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Windows.cs
src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.cs
src/libraries/System.IO.Pipes/src/System/IO/Pipes/ReadWriteCompletionSource.cs

index afdb103..05042ec 100644 (file)
@@ -13,7 +13,7 @@ internal partial class Interop
     {
         [DllImport(Libraries.Kernel32, EntryPoint = "CreateFileW", CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false)]
         internal static extern SafePipeHandle CreateNamedPipeClient(
-            string lpFileName,
+            string? lpFileName,
             int dwDesiredAccess,
             System.IO.FileShare dwShareMode,
             ref SECURITY_ATTRIBUTES secAttrs,
index bb65acd..a4c7b0b 100644 (file)
@@ -10,6 +10,6 @@ internal partial class Interop
     {
         [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false, EntryPoint = "WaitNamedPipeW")]
         [return: MarshalAs(UnmanagedType.Bool)]
-        internal static extern bool WaitNamedPipe(string name, int timeout);
+        internal static extern bool WaitNamedPipe(string? name, int timeout);
     }
 }
index e0d7ef0..a6e0216 100644 (file)
@@ -111,8 +111,8 @@ namespace System.IO.Pipes
         public virtual System.IO.Pipes.PipeTransmissionMode ReadMode { get { throw null; } set { } }
         public Microsoft.Win32.SafeHandles.SafePipeHandle SafePipeHandle { get { throw null; } }
         public virtual System.IO.Pipes.PipeTransmissionMode TransmissionMode { get { throw null; } }
-        public override System.IAsyncResult BeginRead(byte[] buffer, int offset, int count, System.AsyncCallback callback, object state) { throw null; }
-        public override System.IAsyncResult BeginWrite(byte[] buffer, int offset, int count, System.AsyncCallback callback, object state) { throw null; }
+        public override System.IAsyncResult BeginRead(byte[] buffer, int offset, int count, System.AsyncCallback? callback, object? state) { throw null; }
+        public override System.IAsyncResult BeginWrite(byte[] buffer, int offset, int count, System.AsyncCallback? callback, object? state) { throw null; }
         protected internal virtual void CheckPipePropertyOperations() { }
         protected internal void CheckReadOperations() { }
         protected internal void CheckWriteOperations() { }
@@ -120,7 +120,8 @@ namespace System.IO.Pipes
         public override int EndRead(System.IAsyncResult asyncResult) { throw null; }
         public override void EndWrite(System.IAsyncResult asyncResult) { }
         public override void Flush() { }
-        protected void InitializeHandle(Microsoft.Win32.SafeHandles.SafePipeHandle handle, bool isExposed, bool isAsync) { }
+        public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) { throw null; }
+        protected void InitializeHandle(Microsoft.Win32.SafeHandles.SafePipeHandle? handle, bool isExposed, bool isAsync) { }
         public override int Read(byte[] buffer, int offset, int count) { throw null; }
         public override int Read(System.Span<byte> buffer) { throw null; }
         public override System.Threading.Tasks.Task<int> ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
index 37fc718..4ddc4f2 100644 (file)
@@ -1,6 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <TargetFrameworks>$(NetCoreAppCurrent)</TargetFrameworks>
+    <Nullable>enable</Nullable>
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="System.IO.Pipes.cs" />
index a981079..406e159 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System;
 using System.Diagnostics;
 using System.Net.Sockets;
@@ -22,8 +23,8 @@ namespace Microsoft.Win32.SafeHandles
         // and operations that should go through the Socket to be done via _namedPipeSocket.  We keep the
         // Socket's SafeHandle alive as long as this SafeHandle is alive.
 
-        private Socket _namedPipeSocket;
-        private SafeHandle _namedPipeSocketHandle;
+        private Socket? _namedPipeSocket;
+        private SafeHandle? _namedPipeSocketHandle;
 
         internal SafePipeHandle(Socket namedPipeSocket) : base(ownsHandle: true)
         {
@@ -37,8 +38,8 @@ namespace Microsoft.Win32.SafeHandles
             SetHandle(_namedPipeSocketHandle.DangerousGetHandle());
         }
 
-        internal Socket NamedPipeSocket => _namedPipeSocket;
-        internal SafeHandle NamedPipeSocketHandle => _namedPipeSocketHandle;
+        internal Socket? NamedPipeSocket => _namedPipeSocket;
+        internal SafeHandle? NamedPipeSocketHandle => _namedPipeSocketHandle;
 
         protected override void Dispose(bool disposing)
         {
index d6b88e5..aecdadc 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System;
 using System.Runtime.InteropServices;
 using System.Security;
index 31ed0b5..8599e10 100644 (file)
@@ -4,6 +4,7 @@
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <OmitTransitiveCompileReferences>true</OmitTransitiveCompileReferences>
     <TargetFrameworks>$(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix</TargetFrameworks>
+    <Nullable>enable</Nullable>
   </PropertyGroup>
   <!-- Compiled Source Files -->
   <ItemGroup>
index fc57fdf..033a16b 100644 (file)
@@ -34,7 +34,7 @@ namespace System.IO.Pipes
             Create(direction, inheritability, bufferSize, null);
         }
 
-        private void Create(PipeDirection direction, HandleInheritability inheritability, int bufferSize, PipeSecurity pipeSecurity)
+        private void Create(PipeDirection direction, HandleInheritability inheritability, int bufferSize, PipeSecurity? pipeSecurity)
         {
             Debug.Assert(direction != PipeDirection.InOut, "Anonymous pipe direction shouldn't be InOut");
             Debug.Assert(bufferSize >= 0, "bufferSize is negative");
index 1834f98..249aa1e 100644 (file)
@@ -12,7 +12,7 @@ namespace System.IO.Pipes
     /// </summary>
     public sealed partial class AnonymousPipeServerStream : PipeStream
     {
-        private SafePipeHandle _clientHandle;
+        private SafePipeHandle _clientHandle = null!;
         private bool _clientHandleExposed;
 
         public AnonymousPipeServerStream()
index f5a34ba..f0e4f1d 100644 (file)
@@ -13,7 +13,7 @@ namespace System.IO.Pipes
 
         // Using RunContinuationsAsynchronously for compat reasons (old API used ThreadPool.QueueUserWorkItem for continuations)
         internal ConnectionCompletionSource(NamedPipeServerStream server)
-            : base(server._threadPoolBinding, ReadOnlyMemory<byte>.Empty)
+            : base(server._threadPoolBinding!, ReadOnlyMemory<byte>.Empty)
         {
             _serverStream = server;
         }
index cfee043..3025ee6 100644 (file)
@@ -25,7 +25,7 @@ namespace System.IO.Pipes
             // immediately if it isn't.  The only delay will be between the time the server
             // has called Bind and Listen, with the latter immediately following the former.
             var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
-            SafePipeHandle clientHandle = null;
+            SafePipeHandle? clientHandle = null;
             try
             {
                 socket.Connect(new UnixDomainSocketEndPoint(_normalizedPipePath));
index b6689f7..2fa4c15 100644 (file)
@@ -120,7 +120,7 @@ namespace System.IO.Pipes
                 // access request before calling NTCreateFile, so all NamedPipeClientStreams can read
                 // this if they are created (on WinXP SP2 at least)]
                 uint numInstances;
-                if (!Interop.Kernel32.GetNamedPipeHandleStateW(InternalHandle, null, &numInstances, null, null, null, 0))
+                if (!Interop.Kernel32.GetNamedPipeHandleStateW(InternalHandle!, null, &numInstances, null, null, null, 0))
                 {
                     throw WinIOError(Marshal.GetLastWin32Error());
                 }
@@ -135,10 +135,10 @@ namespace System.IO.Pipes
                 return;
 
             PipeSecurity accessControl = this.GetAccessControl();
-            IdentityReference remoteOwnerSid = accessControl.GetOwner(typeof(SecurityIdentifier));
+            IdentityReference? remoteOwnerSid = accessControl.GetOwner(typeof(SecurityIdentifier));
             using (WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent())
             {
-                SecurityIdentifier currentUserSid = currentIdentity.Owner;
+                SecurityIdentifier? currentUserSid = currentIdentity.Owner;
                 if (remoteOwnerSid != currentUserSid)
                 {
                     State = PipeState.Closed;
index 796c3f9..73bc133 100644 (file)
@@ -20,7 +20,7 @@ namespace System.IO.Pipes
         // Maximum interval in milliseconds between which cancellation is checked.
         // Used by ConnectInternal. 50ms is fairly responsive time but really long time for processor.
         private const int CancellationCheckInterval = 50;
-        private readonly string _normalizedPipePath;
+        private readonly string? _normalizedPipePath;
         private readonly TokenImpersonationLevel _impersonationLevel;
         private readonly PipeOptions _pipeOptions;
         private readonly HandleInheritability _inheritability;
index a47efd6..5b0cbe7 100644 (file)
@@ -15,7 +15,7 @@ namespace System.IO.Pipes
 {
     public sealed partial class NamedPipeServerStream : PipeStream
     {
-        private SharedServer _instance;
+        private SharedServer? _instance;
         private PipeDirection _direction;
         private PipeOptions _options;
         private int _inBufferSize;
@@ -62,7 +62,7 @@ namespace System.IO.Pipes
 
             // Use and block on AcceptAsync() rather than using Accept() in order to provide
             // behavior more akin to Windows if the Stream is closed while a connection is pending.
-            Socket accepted = _instance.ListeningSocket.AcceptAsync().GetAwaiter().GetResult();
+            Socket accepted = _instance!.ListeningSocket.AcceptAsync().GetAwaiter().GetResult();
             HandleAcceptedSocket(accepted);
         }
 
@@ -79,7 +79,7 @@ namespace System.IO.Pipes
                 WaitForConnectionAsyncCore();
 
             async Task WaitForConnectionAsyncCore() =>
-               HandleAcceptedSocket(await _instance.ListeningSocket.AcceptAsync().ConfigureAwait(false));
+               HandleAcceptedSocket(await _instance!.ListeningSocket.AcceptAsync().ConfigureAwait(false));
         }
 
         private void HandleAcceptedSocket(Socket acceptedSocket)
@@ -124,7 +124,7 @@ namespace System.IO.Pipes
         {
             CheckDisconnectOperations();
             State = PipeState.Disconnected;
-            InternalHandle.Dispose();
+            InternalHandle!.Dispose();
             InitializeHandle(null, false, false);
         }
 
@@ -135,7 +135,7 @@ namespace System.IO.Pipes
         {
             CheckWriteOperations();
 
-            SafeHandle handle = InternalHandle?.NamedPipeSocketHandle;
+            SafeHandle? handle = InternalHandle?.NamedPipeSocketHandle;
             if (handle == null)
             {
                 throw new InvalidOperationException(SR.InvalidOperation_PipeHandleNotSet);
@@ -178,7 +178,7 @@ namespace System.IO.Pipes
         public void RunAsClient(PipeStreamImpersonationWorker impersonationWorker)
         {
             CheckWriteOperations();
-            SafeHandle handle = InternalHandle?.NamedPipeSocketHandle;
+            SafeHandle? handle = InternalHandle?.NamedPipeSocketHandle;
             if (handle == null)
             {
                 throw new InvalidOperationException(SR.InvalidOperation_PipeHandleNotSet);
@@ -233,7 +233,7 @@ namespace System.IO.Pipes
 
                 lock (s_servers)
                 {
-                    SharedServer server;
+                    SharedServer? server;
                     if (s_servers.TryGetValue(path, out server))
                     {
                         // On Windows, if a subsequent server stream is created for the same pipe and with a different
index ea30ea2..410e969 100644 (file)
@@ -23,7 +23,7 @@ namespace System.IO.Pipes
             {
                 Interop.Kernel32.LoadLibraryEx("sspicli.dll", IntPtr.Zero, Interop.Kernel32.LOAD_LIBRARY_SEARCH_SYSTEM32);
 
-                if (Interop.Kernel32.GetNamedPipeHandleStateW(InternalHandle, null, null, null, null, userName, userNameMaxLength))
+                if (Interop.Kernel32.GetNamedPipeHandleStateW(InternalHandle!, null, null, null, null, userName, userNameMaxLength))
                 {
                     return new string(userName);
                 }
index 994296f..acf2576 100644 (file)
@@ -53,7 +53,7 @@ namespace System.IO.Pipes
         // This overload is used in Mono to implement public constructors.
         private void Create(string pipeName, PipeDirection direction, int maxNumberOfServerInstances,
                 PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize,
-                PipeSecurity pipeSecurity, HandleInheritability inheritability, PipeAccessRights additionalAccessRights)
+                PipeSecurity? pipeSecurity, HandleInheritability inheritability, PipeAccessRights additionalAccessRights)
         {
             Debug.Assert(pipeName != null && pipeName.Length != 0, "fullPipeName is null or empty");
             Debug.Assert(direction >= PipeDirection.In && direction <= PipeDirection.InOut, "invalid pipe direction");
@@ -76,7 +76,7 @@ namespace System.IO.Pipes
 
                 using (WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent())
                 {
-                    SecurityIdentifier identifier = currentIdentity.Owner;
+                    SecurityIdentifier identifier = currentIdentity.Owner!;
 
                     // Grant full control to the owner so multiple servers can be opened.
                     // Full control is the default per MSDN docs for CreateNamedPipe.
@@ -145,7 +145,7 @@ namespace System.IO.Pipes
             }
             else
             {
-                if (!Interop.Kernel32.ConnectNamedPipe(InternalHandle, IntPtr.Zero))
+                if (!Interop.Kernel32.ConnectNamedPipe(InternalHandle!, IntPtr.Zero))
                 {
                     int errorCode = Marshal.GetLastWin32Error();
 
@@ -177,7 +177,7 @@ namespace System.IO.Pipes
 
             if (!IsAsync)
             {
-                return Task.Factory.StartNew(s => ((NamedPipeServerStream)s).WaitForConnection(),
+                return Task.Factory.StartNew(s => ((NamedPipeServerStream)s!).WaitForConnection(),
                     this, cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
             }
 
@@ -189,7 +189,7 @@ namespace System.IO.Pipes
             CheckDisconnectOperations();
 
             // Disconnect the pipe.
-            if (!Interop.Kernel32.DisconnectNamedPipe(InternalHandle))
+            if (!Interop.Kernel32.DisconnectNamedPipe(InternalHandle!))
             {
                 throw Win32Marshal.GetExceptionForLastWin32Error();
             }
@@ -207,7 +207,7 @@ namespace System.IO.Pipes
             const uint UserNameMaxLength = Interop.Kernel32.CREDUI_MAX_USERNAME_LENGTH + 1;
             char* userName = stackalloc char[(int)UserNameMaxLength]; // ~1K
 
-            if (Interop.Kernel32.GetNamedPipeHandleStateW(InternalHandle, null, null, null, null, userName, UserNameMaxLength))
+            if (Interop.Kernel32.GetNamedPipeHandleStateW(InternalHandle!, null, null, null, null, userName, UserNameMaxLength))
             {
                 return new string(userName);
             }
@@ -244,11 +244,11 @@ namespace System.IO.Pipes
         private static readonly RuntimeHelpers.TryCode tryCode = new RuntimeHelpers.TryCode(ImpersonateAndTryCode);
         private static readonly RuntimeHelpers.CleanupCode cleanupCode = new RuntimeHelpers.CleanupCode(RevertImpersonationOnBackout);
 
-        private static void ImpersonateAndTryCode(object helper)
+        private static void ImpersonateAndTryCode(object? helper)
         {
-            ExecuteHelper execHelper = (ExecuteHelper)helper;
+            ExecuteHelper execHelper = (ExecuteHelper)helper!;
 
-            if (Interop.Advapi32.ImpersonateNamedPipeClient(execHelper._handle))
+            if (Interop.Advapi32.ImpersonateNamedPipeClient(execHelper._handle!))
             {
                 execHelper._mustRevert = true;
             }
@@ -264,9 +264,9 @@ namespace System.IO.Pipes
             }
         }
 
-        private static void RevertImpersonationOnBackout(object helper, bool exceptionThrown)
+        private static void RevertImpersonationOnBackout(object? helper, bool exceptionThrown)
         {
-            ExecuteHelper execHelper = (ExecuteHelper)helper;
+            ExecuteHelper execHelper = (ExecuteHelper)helper!;
 
             if (execHelper._mustRevert)
             {
@@ -280,12 +280,12 @@ namespace System.IO.Pipes
         internal class ExecuteHelper
         {
             internal PipeStreamImpersonationWorker _userCode;
-            internal SafePipeHandle _handle;
+            internal SafePipeHandle? _handle;
             internal bool _mustRevert;
             internal int _impersonateErrorCode;
             internal int _revertImpersonateErrorCode;
 
-            internal ExecuteHelper(PipeStreamImpersonationWorker userCode, SafePipeHandle handle)
+            internal ExecuteHelper(PipeStreamImpersonationWorker userCode, SafePipeHandle? handle)
             {
                 _userCode = userCode;
                 _handle = handle;
@@ -304,7 +304,7 @@ namespace System.IO.Pipes
 
             var completionSource = new ConnectionCompletionSource(this);
 
-            if (!Interop.Kernel32.ConnectNamedPipe(InternalHandle, completionSource.Overlapped))
+            if (!Interop.Kernel32.ConnectNamedPipe(InternalHandle!, completionSource.Overlapped))
             {
                 int errorCode = Marshal.GetLastWin32Error();
 
index 3118965..484e138 100644 (file)
@@ -43,7 +43,7 @@ namespace System.IO.Pipes
             _pinnedMemory = bufferToPin.Pin();
             _overlapped = _threadPoolBinding.AllocateNativeOverlapped((errorCode, numBytes, pOverlapped) =>
             {
-                var completionSource = (PipeCompletionSource<TResult>)ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped);
+                var completionSource = (PipeCompletionSource<TResult>)ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped)!;
                 Debug.Assert(completionSource.Overlapped == pOverlapped);
 
                 completionSource.AsyncCallback(errorCode, numBytes);
@@ -70,7 +70,7 @@ namespace System.IO.Pipes
                 if (state == NoResult)
                 {
                     // Register the cancellation
-                    _cancellationRegistration = cancellationToken.UnsafeRegister(thisRef => ((PipeCompletionSource<TResult>)thisRef).Cancel(), this);
+                    _cancellationRegistration = cancellationToken.UnsafeRegister(thisRef => ((PipeCompletionSource<TResult>)thisRef!).Cancel(), this);
 
                     // Grab the state for case if IO completed while we were setting the registration.
                     state = Interlocked.Exchange(ref _state, NoResult);
index eb26265..7a826e2 100644 (file)
@@ -55,7 +55,7 @@ namespace System.IO.Pipes
 
             for (int i = 0; i < rules.Count; i++)
             {
-                PipeAccessRule fsrule = rules[i] as PipeAccessRule;
+                PipeAccessRule? fsrule = rules[i] as PipeAccessRule;
 
                 if ((fsrule != null) && (fsrule.PipeAccessRights == rule.PipeAccessRights)
                         && (fsrule.IdentityReference == rule.IdentityReference)
@@ -97,7 +97,7 @@ namespace System.IO.Pipes
 
             for (int i = 0; i < rules.Count; i++)
             {
-                PipeAccessRule fsrule = rules[i] as PipeAccessRule;
+                PipeAccessRule? fsrule = rules[i] as PipeAccessRule;
 
                 if ((fsrule != null) && (fsrule.PipeAccessRights == rule.PipeAccessRights)
                     && (fsrule.IdentityReference == rule.IdentityReference)
index 96994ab..fdd1d92 100644 (file)
@@ -109,10 +109,11 @@ namespace System.IO.Pipes
 
         private unsafe int ReadCore(Span<byte> buffer)
         {
+            Debug.Assert(_handle != null);
             DebugAssertHandleValid(_handle);
 
             // For named pipes, receive on the socket.
-            Socket socket = _handle.NamedPipeSocket;
+            Socket? socket = _handle.NamedPipeSocket;
             if (socket != null)
             {
                 // For a blocking socket, we could simply use the same Read syscall as is done
@@ -140,10 +141,11 @@ namespace System.IO.Pipes
 
         private unsafe void WriteCore(ReadOnlySpan<byte> buffer)
         {
+            Debug.Assert(_handle != null);
             DebugAssertHandleValid(_handle);
 
             // For named pipes, send to the socket.
-            Socket socket = _handle.NamedPipeSocket;
+            Socket? socket = _handle.NamedPipeSocket;
             if (socket != null)
             {
                 // For a blocking socket, we could simply use the same Write syscall as is done
@@ -181,7 +183,7 @@ namespace System.IO.Pipes
 
             try
             {
-                return await InternalHandle.NamedPipeSocket.ReceiveAsync(destination, SocketFlags.None, cancellationToken).ConfigureAwait(false);
+                return await InternalHandle!.NamedPipeSocket.ReceiveAsync(destination, SocketFlags.None, cancellationToken).ConfigureAwait(false);
             }
             catch (SocketException e)
             {
@@ -197,7 +199,7 @@ namespace System.IO.Pipes
             {
                 while (source.Length > 0)
                 {
-                    int bytesWritten = await _handle.NamedPipeSocket.SendAsync(source, SocketFlags.None, cancellationToken).ConfigureAwait(false);
+                    int bytesWritten = await _handle!.NamedPipeSocket.SendAsync(source, SocketFlags.None, cancellationToken).ConfigureAwait(false);
                     Debug.Assert(bytesWritten > 0 && bytesWritten <= source.Length);
                     source = source.Slice(bytesWritten);
                 }
@@ -310,7 +312,7 @@ namespace System.IO.Pipes
         /// semaphore.  Since we don't delegate to the base stream for Read/WriteAsync due
         /// to having specialized support for cancellation, we do the same serialization here.
         /// </summary>
-        private SemaphoreSlim _asyncActiveSemaphore;
+        private SemaphoreSlim? _asyncActiveSemaphore;
 
         private SemaphoreSlim EnsureAsyncActiveSemaphoreInitialized()
         {
@@ -416,7 +418,7 @@ namespace System.IO.Pipes
             }
         }
 
-        internal static Exception CreateExceptionForLastError(string pipeName = null)
+        internal static Exception CreateExceptionForLastError(string? pipeName = null)
         {
             Interop.ErrorInfo error = Interop.Sys.GetLastErrorInfo();
             return error.Error == Interop.Error.ENOTSUP ?
index 8a9a34e..8feb3b6 100644 (file)
@@ -14,7 +14,7 @@ namespace System.IO.Pipes
     public abstract partial class PipeStream : Stream
     {
         internal const bool CheckOperationsRequiresSetHandle = true;
-        internal ThreadPoolBoundHandle _threadPoolBinding;
+        internal ThreadPoolBoundHandle? _threadPoolBinding;
 
         internal static string GetPipePath(string serverName, string pipeName)
         {
@@ -57,7 +57,7 @@ namespace System.IO.Pipes
         private unsafe int ReadCore(Span<byte> buffer)
         {
             int errorCode = 0;
-            int r = ReadFileNative(_handle, buffer, null, out errorCode);
+            int r = ReadFileNative(_handle!, buffer, null, out errorCode);
 
             if (r == -1)
             {
@@ -89,7 +89,7 @@ namespace System.IO.Pipes
             int r;
             unsafe
             {
-                r = ReadFileNative(_handle, buffer.Span, completionSource.Overlapped, out errorCode);
+                r = ReadFileNative(_handle!, buffer.Span, completionSource.Overlapped, out errorCode);
             }
 
             // ReadFile, the OS version, will return 0 on failure, but this ReadFileNative wrapper
@@ -137,7 +137,7 @@ namespace System.IO.Pipes
         private unsafe void WriteCore(ReadOnlySpan<byte> buffer)
         {
             int errorCode = 0;
-            int r = WriteFileNative(_handle, buffer, null, out errorCode);
+            int r = WriteFileNative(_handle!, buffer, null, out errorCode);
 
             if (r == -1)
             {
@@ -155,7 +155,7 @@ namespace System.IO.Pipes
             int r;
             unsafe
             {
-                r = WriteFileNative(_handle, buffer.Span, completionSource.Overlapped, out errorCode);
+                r = WriteFileNative(_handle!, buffer.Span, completionSource.Overlapped, out errorCode);
             }
 
             // WriteFile, the OS version, will return 0 on failure, but this WriteFileNative
@@ -188,7 +188,7 @@ namespace System.IO.Pipes
             }
 
             // Block until other end of the pipe has read everything.
-            if (!Interop.Kernel32.FlushFileBuffers(_handle))
+            if (!Interop.Kernel32.FlushFileBuffers(_handle!))
             {
                 throw WinIOError(Marshal.GetLastWin32Error());
             }
@@ -205,7 +205,7 @@ namespace System.IO.Pipes
                 if (_isFromExistingHandle)
                 {
                     uint pipeFlags;
-                    if (!Interop.Kernel32.GetNamedPipeInfo(_handle, &pipeFlags, null, null, null))
+                    if (!Interop.Kernel32.GetNamedPipeInfo(_handle!, &pipeFlags, null, null, null))
                     {
                         throw WinIOError(Marshal.GetLastWin32Error());
                     }
@@ -238,7 +238,7 @@ namespace System.IO.Pipes
                 }
 
                 uint inBufferSize;
-                if (!Interop.Kernel32.GetNamedPipeInfo(_handle, null, null, &inBufferSize, null))
+                if (!Interop.Kernel32.GetNamedPipeInfo(_handle!, null, null, &inBufferSize, null))
                 {
                     throw WinIOError(Marshal.GetLastWin32Error());
                 }
@@ -268,7 +268,7 @@ namespace System.IO.Pipes
                 {
                     outBufferSize = _outBufferSize;
                 }
-                else if (!Interop.Kernel32.GetNamedPipeInfo(_handle, null, &outBufferSize, null, null))
+                else if (!Interop.Kernel32.GetNamedPipeInfo(_handle!, null, &outBufferSize, null, null))
                 {
                     throw WinIOError(Marshal.GetLastWin32Error());
                 }
@@ -304,7 +304,7 @@ namespace System.IO.Pipes
                 unsafe
                 {
                     int pipeReadType = (int)value << 1;
-                    if (!Interop.Kernel32.SetNamedPipeHandleState(_handle, &pipeReadType, IntPtr.Zero, IntPtr.Zero))
+                    if (!Interop.Kernel32.SetNamedPipeHandleState(_handle!, &pipeReadType, IntPtr.Zero, IntPtr.Zero))
                     {
                         throw WinIOError(Marshal.GetLastWin32Error());
                     }
@@ -404,7 +404,7 @@ namespace System.IO.Pipes
             return secAttrs;
         }
 
-        internal static unsafe Interop.Kernel32.SECURITY_ATTRIBUTES GetSecAttrs(HandleInheritability inheritability, PipeSecurity pipeSecurity, ref GCHandle pinningHandle)
+        internal static unsafe Interop.Kernel32.SECURITY_ATTRIBUTES GetSecAttrs(HandleInheritability inheritability, PipeSecurity? pipeSecurity, ref GCHandle pinningHandle)
         {
             Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(inheritability);
 
@@ -466,7 +466,7 @@ namespace System.IO.Pipes
                     // For invalid handles, detect the error and mark our handle
                     // as invalid to give slightly better error messages.  Also
                     // help ensure we avoid handle recycling bugs.
-                    _handle.SetHandleAsInvalid();
+                    _handle!.SetHandleAsInvalid();
                     _state = PipeState.Broken;
                     break;
             }
index b2d786b..142f514 100644 (file)
@@ -16,7 +16,7 @@ namespace System.IO.Pipes
         internal const string AnonymousPipeName = "anonymous";
         private static readonly Task<int> s_zeroTask = Task.FromResult(0);
 
-        private SafePipeHandle _handle;
+        private SafePipeHandle? _handle;
         private bool _canRead;
         private bool _canWrite;
         private bool _isAsync;
@@ -94,7 +94,7 @@ namespace System.IO.Pipes
         // Once a PipeStream has a handle ready, it should call this method to set up the PipeStream.  If
         // the pipe is in a connected state already, it should also set the IsConnected (protected) property.
         // This method may also be called to uninitialize a handle, setting it to null.
-        protected void InitializeHandle(SafePipeHandle handle, bool isExposed, bool isAsync)
+        protected void InitializeHandle(SafePipeHandle? handle, bool isExposed, bool isAsync)
         {
             if (isAsync && handle != null)
             {
@@ -199,7 +199,7 @@ namespace System.IO.Pipes
             return ReadAsyncCore(buffer, cancellationToken);
         }
 
-        public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
+        public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
         {
             if (_isAsync)
                 return TaskToApm.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), callback, state);
@@ -305,7 +305,7 @@ namespace System.IO.Pipes
             return new ValueTask(WriteAsyncCore(buffer, cancellationToken));
         }
 
-        public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
+        public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
         {
             if (_isAsync)
                 return TaskToApm.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), callback, state);
@@ -480,7 +480,7 @@ namespace System.IO.Pipes
             }
         }
 
-        internal SafePipeHandle InternalHandle
+        internal SafePipeHandle? InternalHandle
         {
             get
             {
index b75b872..979fcc1 100644 (file)
@@ -16,7 +16,7 @@ namespace System.IO.Pipes
         private int _numBytes; // number of buffer read OR written
 
         internal ReadWriteCompletionSource(PipeStream stream, ReadOnlyMemory<byte> bufferToPin, bool isWrite)
-            : base(stream._threadPoolBinding, bufferToPin)
+            : base(stream._threadPoolBinding!, bufferToPin)
         {
             _pipeStream = stream;
             _isWrite = isWrite;