Delete DebugThreadTracking from networking code (#36549)
authorStephen Toub <stoub@microsoft.com>
Fri, 15 May 2020 21:47:15 +0000 (17:47 -0400)
committerGitHub <noreply@github.com>
Fri, 15 May 2020 21:47:15 +0000 (17:47 -0400)
The System.Net.* libs in dotnet/runtime inherited this from .NET Framework.  To my knowledge it's not once helped flag any issues in dotnet/runtime, it's only built into debug builds, it's become very inconsistent as the code base has evolved, and it's just cluttering stuff up.  So, goodbye.

21 files changed:
src/libraries/Common/src/System/Net/DebugCriticalHandleMinusOneIsInvalid.cs
src/libraries/Common/src/System/Net/DebugCriticalHandleZeroOrMinusOneIsInvalid.cs
src/libraries/Common/src/System/Net/DebugSafeHandleMinusOneIsInvalid.cs
src/libraries/Common/src/System/Net/Logging/DebugThreadTracking.cs [deleted file]
src/libraries/System.Net.Http/src/System.Net.Http.csproj
src/libraries/System.Net.HttpListener/src/System.Net.HttpListener.csproj
src/libraries/System.Net.Mail/src/System.Net.Mail.csproj
src/libraries/System.Net.Mail/tests/Unit/System.Net.Mail.Unit.Tests.csproj
src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj
src/libraries/System.Net.NameResolution/tests/PalTests/Fakes/DebugThreadTracking.cs [deleted file]
src/libraries/System.Net.NameResolution/tests/PalTests/System.Net.NameResolution.Pal.Tests.csproj
src/libraries/System.Net.Requests/src/System.Net.Requests.csproj
src/libraries/System.Net.Requests/src/System/Net/HttpWebRequest.cs
src/libraries/System.Net.Requests/src/System/Net/TimerThread.cs
src/libraries/System.Net.Security/src/System.Net.Security.csproj
src/libraries/System.Net.Security/src/System/Net/Security/AuthenticatedStream.cs
src/libraries/System.Net.Security/src/System/Net/Security/NegotiateStream.cs
src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj
src/libraries/System.Net.Sockets/src/System/Net/Sockets/BaseOverlappedAsyncResult.Windows.cs
src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs
src/libraries/System.Net.Sockets/src/System/Net/Sockets/TCPClient.cs

index 38c3a40..eed8ccb 100644 (file)
@@ -33,7 +33,6 @@ namespace System.Net
 
         ~DebugCriticalHandleMinusOneIsInvalid()
         {
-            DebugThreadTracking.SetThreadSource(ThreadKinds.Finalization);
             if (NetEventSource.IsEnabled) NetEventSource.Info(this, _trace);
         }
     }
index 33bca4d..0d993cd 100644 (file)
@@ -33,7 +33,6 @@ namespace System.Net
 
         ~DebugCriticalHandleZeroOrMinusOneIsInvalid()
         {
-            DebugThreadTracking.SetThreadSource(ThreadKinds.Finalization);
             if (NetEventSource.IsEnabled) NetEventSource.Info(this, _trace);
         }
     }
index 5cf3352..4fd2c5b 100644 (file)
@@ -33,7 +33,6 @@ namespace System.Net
 
         ~DebugSafeHandleMinusOneIsInvalid()
         {
-            DebugThreadTracking.SetThreadSource(ThreadKinds.Finalization);
             if (NetEventSource.IsEnabled) NetEventSource.Info(this, _trace);
         }
     }
diff --git a/src/libraries/Common/src/System/Net/Logging/DebugThreadTracking.cs b/src/libraries/Common/src/System/Net/Logging/DebugThreadTracking.cs
deleted file mode 100644 (file)
index eba97da..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// 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.Collections.Generic;
-
-namespace System.Net
-{
-    internal static class DebugThreadTracking
-    {
-        [ThreadStatic]
-        private static Stack<ThreadKinds>? t_threadKindStack;
-
-        private static Stack<ThreadKinds> ThreadKindStack => t_threadKindStack ?? (t_threadKindStack = new Stack<ThreadKinds>());
-
-        internal static ThreadKinds CurrentThreadKind => ThreadKindStack.Count > 0 ? ThreadKindStack.Peek() : ThreadKinds.Other;
-
-        internal static IDisposable? SetThreadKind(ThreadKinds kind)
-        {
-            if ((kind & ThreadKinds.SourceMask) != ThreadKinds.Unknown)
-            {
-                throw new InternalException(kind);
-            }
-
-            // Ignore during shutdown.
-            if (Environment.HasShutdownStarted)
-            {
-                return null;
-            }
-
-            ThreadKinds threadKind = CurrentThreadKind;
-            ThreadKinds source = threadKind & ThreadKinds.SourceMask;
-
-            // Special warnings when doing dangerous things on a thread.
-            if ((threadKind & ThreadKinds.User) != 0 && (kind & ThreadKinds.System) != 0)
-            {
-                if (NetEventSource.IsEnabled) NetEventSource.Error(null, "Thread changed from User to System; user's thread shouldn't be hijacked.");
-            }
-
-            if ((threadKind & ThreadKinds.Async) != 0 && (kind & ThreadKinds.Sync) != 0)
-            {
-                if (NetEventSource.IsEnabled) NetEventSource.Error(null, "Thread changed from Async to Sync, may block an Async thread.");
-            }
-            else if ((threadKind & (ThreadKinds.Other | ThreadKinds.CompletionPort)) == 0 && (kind & ThreadKinds.Sync) != 0)
-            {
-                if (NetEventSource.IsEnabled) NetEventSource.Error(null, "Thread from a limited resource changed to Sync, may deadlock or bottleneck.");
-            }
-
-            ThreadKindStack.Push(
-                (((kind & ThreadKinds.OwnerMask) == 0 ? threadKind : kind) & ThreadKinds.OwnerMask) |
-                (((kind & ThreadKinds.SyncMask) == 0 ? threadKind : kind) & ThreadKinds.SyncMask) |
-                (kind & ~(ThreadKinds.OwnerMask | ThreadKinds.SyncMask)) |
-                source);
-
-            if (CurrentThreadKind != threadKind)
-            {
-                if (NetEventSource.IsEnabled) NetEventSource.Info(null, $"Thread becomes:({CurrentThreadKind})");
-            }
-
-            return new ThreadKindFrame();
-        }
-
-        private class ThreadKindFrame : IDisposable
-        {
-            private readonly int _frameNumber;
-
-            internal ThreadKindFrame()
-            {
-                _frameNumber = ThreadKindStack.Count;
-            }
-
-            void IDisposable.Dispose()
-            {
-                // Ignore during shutdown.
-                if (Environment.HasShutdownStarted)
-                {
-                    return;
-                }
-
-                if (_frameNumber != ThreadKindStack.Count)
-                {
-                    throw new InternalException(_frameNumber);
-                }
-
-                ThreadKinds previous = ThreadKindStack.Pop();
-
-                if (CurrentThreadKind != previous && NetEventSource.IsEnabled)
-                {
-                    if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"Thread reverts:({CurrentThreadKind})");
-                }
-            }
-        }
-
-        internal static void SetThreadSource(ThreadKinds source)
-        {
-            if ((source & ThreadKinds.SourceMask) != source || source == ThreadKinds.Unknown)
-            {
-                throw new ArgumentException("Must specify the thread source.", nameof(source));
-            }
-
-            if (ThreadKindStack.Count == 0)
-            {
-                ThreadKindStack.Push(source);
-                return;
-            }
-
-            if (ThreadKindStack.Count > 1)
-            {
-                if (NetEventSource.IsEnabled) NetEventSource.Error(null, "SetThreadSource must be called at the base of the stack, or the stack has been corrupted.");
-                while (ThreadKindStack.Count > 1)
-                {
-                    ThreadKindStack.Pop();
-                }
-            }
-
-            if (ThreadKindStack.Peek() != source)
-            {
-                if (NetEventSource.IsEnabled) NetEventSource.Error(null, "The stack has been corrupted.");
-                ThreadKinds last = ThreadKindStack.Pop() & ThreadKinds.SourceMask;
-                if (last != source && last != ThreadKinds.Other && NetEventSource.IsEnabled)
-                {
-                    NetEventSource.Fail(null, $"Thread source changed.|Was:({last}) Now:({source})");
-                }
-                ThreadKindStack.Push(source);
-            }
-        }
-    }
-
-    [Flags]
-    internal enum ThreadKinds
-    {
-        Unknown = 0x0000,
-
-        // Mutually exclusive.
-        User = 0x0001,     // Thread has entered via an API.
-        System = 0x0002,     // Thread has entered via a system callback (e.g. completion port) or is our own thread.
-
-        // Mutually exclusive.
-        Sync = 0x0004,     // Thread should block.
-        Async = 0x0008,     // Thread should not block.
-
-        // Mutually exclusive, not always known for a user thread.  Never changes.
-        Timer = 0x0010,     // Thread is the timer thread.  (Can't call user code.)
-        CompletionPort = 0x0020,     // Thread is a ThreadPool completion-port thread.
-        Worker = 0x0040,     // Thread is a ThreadPool worker thread.
-        Finalization = 0x0080,     // Thread is the finalization thread.
-        Other = 0x0100,     // Unknown source.
-
-        OwnerMask = User | System,
-        SyncMask = Sync | Async,
-        SourceMask = Timer | CompletionPort | Worker | Finalization | Other,
-
-        // Useful "macros"
-        SafeSources = SourceMask & ~(Timer | Finalization),  // Methods that "unsafe" sources can call must be explicitly marked.
-        ThreadPool = CompletionPort | Worker,               // Like Thread.CurrentThread.IsThreadPoolThread
-    }
-}
index ee9e25b..2f7eb9d 100644 (file)
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <OutputType>Library</OutputType>
     <AssemblyName>System.Net.Http</AssemblyName>
              Link="Common\System\Net\NegotiationInfoClass.cs" />
     <Compile Include="$(CommonPath)System\Net\InternalException.cs"
              Link="Common\System\Net\InternalException.cs" />
-    <Compile Include="$(CommonPath)System\Net\Logging\DebugThreadTracking.cs"
-             Link="Common\System\Net\Logging\DebugThreadTracking.cs" />
     <Compile Include="$(CommonPath)System\Net\DebugSafeHandle.cs"
              Link="Common\System\Net\DebugSafeHandle.cs" />
     <Compile Include="$(CommonPath)System\Net\DebugCriticalHandleMinusOneIsInvalid.cs"
index c92d428..b27d2d0 100644 (file)
              Link="Common\System\Collections\Generic\BidirectionalDictionary.cs" />
     <Compile Include="$(CommonPath)System\NotImplemented.cs"
              Link="Common\System\NotImplemented.cs" />
-    <Compile Include="$(CommonPath)System\Net\Logging\DebugThreadTracking.cs"
-             Link="Common\System\Net\Logging\DebugThreadTracking.cs" />
     <Compile Include="$(CommonPath)System\Net\ContextFlagsPal.cs"
              Link="Common\System\Net\ContextFlagsPal.cs" />
     <Compile Include="$(CommonPath)System\Net\NegotiationInfoClass.cs"
index adc2595..9567cbd 100644 (file)
              Link="Common\System\Collections\Generic\BidirectionalDictionary.cs" />
     <Compile Include="$(CommonPath)System\NotImplemented.cs"
              Link="Common\System\NotImplemented.cs" />
-    <Compile Include="$(CommonPath)System\Net\Logging\DebugThreadTracking.cs"
-             Link="Common\System\Net\Logging\DebugThreadTracking.cs" />
     <Compile Include="$(CommonPath)System\Net\ContextFlagsPal.cs"
              Link="Common\System\Net\ContextFlagsPal.cs" />
     <Compile Include="$(CommonPath)System\Net\NegotiationInfoClass.cs"
   <ItemGroup Condition=" '$(TargetsWindows)' == 'true'">
     <Reference Include="System.Memory" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
index 5a72197..d4da9df 100644 (file)
              Link="Common\System\Collections\Generic\BidirectionalDictionary.cs" />
     <Compile Include="$(CommonPath)System\NotImplemented.cs"
              Link="Common\System\NotImplemented.cs" />
-    <Compile Include="$(CommonPath)System\Net\Logging\DebugThreadTracking.cs"
-             Link="Common\System\Net\Logging\DebugThreadTracking.cs" />
     <Compile Include="$(CommonPath)System\Net\ContextFlagsPal.cs"
              Link="Common\System\Net\ContextFlagsPal.cs" />
     <Compile Include="$(CommonPath)System\Net\NegotiationInfoClass.cs"
     <Compile Include="$(CommonPath)Interop\Windows\SspiCli\SSPIWrapper.cs"
              Link="Common\Interop\Windows\SspiCli\SSPIWrapper.cs" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
index 7d5e1cc..498f4e8 100644 (file)
@@ -10,8 +10,6 @@
     <Compile Include="System\Net\IPHostEntry.cs" />
     <Compile Include="System\Net\NetEventSource.NameResolution.cs" />
     <!-- Logging -->
-    <Compile Include="$(CommonPath)System\Net\Logging\DebugThreadTracking.cs"
-             Link="Common\System\Net\Logging\DebugThreadTracking.cs" />
     <Compile Include="$(CommonPath)System\Net\Logging\NetEventSource.Common.cs"
              Link="Common\System\Net\Logging\NetEventSource.Common.cs" />
     <Compile Include="$(CommonPath)System\Net\InternalException.cs"
diff --git a/src/libraries/System.Net.NameResolution/tests/PalTests/Fakes/DebugThreadTracking.cs b/src/libraries/System.Net.NameResolution/tests/PalTests/Fakes/DebugThreadTracking.cs
deleted file mode 100644 (file)
index ebe478f..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Net
-{
-    public static class DebugThreadTracking
-    {
-        internal static void SetThreadSource(ThreadKinds source)
-        {
-        }
-    }
-
-    [Flags]
-    internal enum ThreadKinds
-    {
-        Unknown = 0x0000,
-
-        // Mutually exclusive.
-        User = 0x0001,     // Thread has entered via an API.
-        System = 0x0002,     // Thread has entered via a system callback (e.g. completion port) or is our own thread.
-
-        // Mutually exclusive.
-        Sync = 0x0004,     // Thread should block.
-        Async = 0x0008,     // Thread should not block.
-
-        // Mutually exclusive, not always known for a user thread.  Never changes.
-        Timer = 0x0010,     // Thread is the timer thread.  (Can't call user code.)
-        CompletionPort = 0x0020,     // Thread is a ThreadPool completion-port thread.
-        Worker = 0x0040,     // Thread is a ThreadPool worker thread.
-        Finalization = 0x0080,     // Thread is the finalization thread.
-        Other = 0x0100,     // Unknown source.
-
-        OwnerMask = User | System,
-        SyncMask = Sync | Async,
-        SourceMask = Timer | CompletionPort | Worker | Finalization | Other,
-
-        // Useful "macros"
-        SafeSources = SourceMask & ~(Timer | Finalization),  // Methods that "unsafe" sources can call must be explicitly marked.
-        ThreadPool = CompletionPort | Worker,               // Like Thread.CurrentThread.IsThreadPoolThread
-    }
-}
index 559c1bf..70e8ac2 100644 (file)
@@ -14,7 +14,6 @@
              Link="ProductionCode\System\Net\IPHostEntry.cs" />
     <Compile Include="Fakes\FakeContextAwareResult.cs" />
     <Compile Include="NameResolutionPalTests.cs" />
-    <Compile Include="Fakes\DebugThreadTracking.cs" />
     <Compile Include="Fakes\DnsFake.cs" />
     <Compile Include="Fakes\IPAddressFakeExtensions.cs" />
     <Compile Include="$(CommonPath)System\Net\Logging\NetEventSource.Common.cs"
index 0b81d07..8b74881 100644 (file)
@@ -49,8 +49,6 @@
              Link="Common\System\Net\InternalException.cs" />
     <Compile Include="$(CommonPath)System\Net\Logging\NetEventSource.Common.cs"
              Link="Common\System\Net\Logging\NetEventSource.Common.cs" />
-    <Compile Include="$(CommonPath)System\Net\Logging\DebugThreadTracking.cs"
-             Link="Common\System\Net\Logging\DebugThreadTracking.cs" />
     <Compile Include="$(CommonPath)System\Net\HttpDateParser.cs"
              Link="Common\System\Net\HttpDateParser.cs" />
     <Compile Include="$(CommonPath)System\Net\HttpKnownHeaderNames.cs"
index ca3d4a6..33a7936 100644 (file)
@@ -439,49 +439,42 @@ namespace System.Net
             }
             set
             {
-#if DEBUG
-                using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
+                bool fChunked;
+                //
+                // on blank string, remove current header
+                //
+                if (string.IsNullOrWhiteSpace(value))
                 {
-#endif
-                    bool fChunked;
                     //
-                    // on blank string, remove current header
+                    // if the value is blank, then remove the header
                     //
-                    if (string.IsNullOrWhiteSpace(value))
-                    {
-                        //
-                        // if the value is blank, then remove the header
-                        //
-                        _webHeaderCollection.Remove(HttpKnownHeaderNames.TransferEncoding);
-                        return;
-                    }
+                    _webHeaderCollection.Remove(HttpKnownHeaderNames.TransferEncoding);
+                    return;
+                }
 
-                    //
-                    // if not check if the user is trying to set chunked:
-                    //
-                    fChunked = (value.IndexOf(ChunkedHeader, StringComparison.OrdinalIgnoreCase) != -1);
+                //
+                // if not check if the user is trying to set chunked:
+                //
+                fChunked = (value.IndexOf(ChunkedHeader, StringComparison.OrdinalIgnoreCase) != -1);
 
-                    //
-                    // prevent them from adding chunked, or from adding an Encoding without
-                    // turning on chunked, the reason is due to the HTTP Spec which prevents
-                    // additional encoding types from being used without chunked
-                    //
-                    if (fChunked)
-                    {
-                        throw new ArgumentException(SR.net_nochunked, nameof(value));
-                    }
-                    else if (!SendChunked)
-                    {
-                        throw new InvalidOperationException(SR.net_needchunked);
-                    }
-                    else
-                    {
-                        string checkedValue = HttpValidationHelpers.CheckBadHeaderValueChars(value);
-                        _webHeaderCollection[HttpKnownHeaderNames.TransferEncoding] = checkedValue;
-                    }
-#if DEBUG
+                //
+                // prevent them from adding chunked, or from adding an Encoding without
+                // turning on chunked, the reason is due to the HTTP Spec which prevents
+                // additional encoding types from being used without chunked
+                //
+                if (fChunked)
+                {
+                    throw new ArgumentException(SR.net_nochunked, nameof(value));
+                }
+                else if (!SendChunked)
+                {
+                    throw new InvalidOperationException(SR.net_needchunked);
+                }
+                else
+                {
+                    string checkedValue = HttpValidationHelpers.CheckBadHeaderValueChars(value);
+                    _webHeaderCollection[HttpKnownHeaderNames.TransferEncoding] = checkedValue;
                 }
-#endif
             }
         }
 
@@ -587,42 +580,35 @@ namespace System.Net
             }
             set
             {
-#if DEBUG
-                using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
-                {
-#endif
-                    bool fKeepAlive;
-                    bool fClose;
+                bool fKeepAlive;
+                bool fClose;
 
-                    //
-                    // on blank string, remove current header
-                    //
-                    if (string.IsNullOrWhiteSpace(value))
-                    {
-                        _webHeaderCollection.Remove(HttpKnownHeaderNames.Connection);
-                        return;
-                    }
+                //
+                // on blank string, remove current header
+                //
+                if (string.IsNullOrWhiteSpace(value))
+                {
+                    _webHeaderCollection.Remove(HttpKnownHeaderNames.Connection);
+                    return;
+                }
 
-                    fKeepAlive = (value.IndexOf("keep-alive", StringComparison.OrdinalIgnoreCase) != -1);
-                    fClose = (value.IndexOf("close", StringComparison.OrdinalIgnoreCase) != -1);
+                fKeepAlive = (value.IndexOf("keep-alive", StringComparison.OrdinalIgnoreCase) != -1);
+                fClose = (value.IndexOf("close", StringComparison.OrdinalIgnoreCase) != -1);
 
-                    //
-                    // Prevent keep-alive and close from being added
-                    //
+                //
+                // Prevent keep-alive and close from being added
+                //
 
-                    if (fKeepAlive ||
-                        fClose)
-                    {
-                        throw new ArgumentException(SR.net_connarg, nameof(value));
-                    }
-                    else
-                    {
-                        string checkedValue = HttpValidationHelpers.CheckBadHeaderValueChars(value);
-                        _webHeaderCollection[HttpKnownHeaderNames.Connection] = checkedValue;
-                    }
-#if DEBUG
+                if (fKeepAlive ||
+                    fClose)
+                {
+                    throw new ArgumentException(SR.net_connarg, nameof(value));
+                }
+                else
+                {
+                    string checkedValue = HttpValidationHelpers.CheckBadHeaderValueChars(value);
+                    _webHeaderCollection[HttpKnownHeaderNames.Connection] = checkedValue;
                 }
-#endif
             }
         }
 
@@ -644,41 +630,34 @@ namespace System.Net
             }
             set
             {
-#if DEBUG
-                using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
-                {
-#endif
-                    // only remove everything other than 100-cont
-                    bool fContinue100;
+                // only remove everything other than 100-cont
+                bool fContinue100;
 
-                    //
-                    // on blank string, remove current header
-                    //
+                //
+                // on blank string, remove current header
+                //
 
-                    if (string.IsNullOrWhiteSpace(value))
-                    {
-                        _webHeaderCollection.Remove(HttpKnownHeaderNames.Expect);
-                        return;
-                    }
+                if (string.IsNullOrWhiteSpace(value))
+                {
+                    _webHeaderCollection.Remove(HttpKnownHeaderNames.Expect);
+                    return;
+                }
 
-                    //
-                    // Prevent 100-continues from being added
-                    //
+                //
+                // Prevent 100-continues from being added
+                //
 
-                    fContinue100 = (value.IndexOf(ContinueHeader, StringComparison.OrdinalIgnoreCase) != -1);
+                fContinue100 = (value.IndexOf(ContinueHeader, StringComparison.OrdinalIgnoreCase) != -1);
 
-                    if (fContinue100)
-                    {
-                        throw new ArgumentException(SR.net_no100, nameof(value));
-                    }
-                    else
-                    {
-                        string checkedValue = HttpValidationHelpers.CheckBadHeaderValueChars(value);
-                        _webHeaderCollection[HttpKnownHeaderNames.Expect] = checkedValue;
-                    }
-#if DEBUG
+                if (fContinue100)
+                {
+                    throw new ArgumentException(SR.net_no100, nameof(value));
+                }
+                else
+                {
+                    string checkedValue = HttpValidationHelpers.CheckBadHeaderValueChars(value);
+                    _webHeaderCollection[HttpKnownHeaderNames.Expect] = checkedValue;
                 }
-#endif
             }
         }
 
@@ -1435,42 +1414,28 @@ namespace System.Net
 
         private DateTime GetDateHeaderHelper(string headerName)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
-            {
-#endif
-                string? headerValue = _webHeaderCollection[headerName];
+            string? headerValue = _webHeaderCollection[headerName];
 
-                if (headerValue == null)
-                {
-                    return DateTime.MinValue; // MinValue means header is not present
-                }
-                if (HttpDateParser.TryParse(headerValue, out DateTimeOffset dateTimeOffset))
-                {
-                    return dateTimeOffset.LocalDateTime;
-                }
-                else
-                {
-                    throw new ProtocolViolationException(SR.net_baddate);
-                }
-#if DEBUG
+            if (headerValue == null)
+            {
+                return DateTime.MinValue; // MinValue means header is not present
+            }
+            if (HttpDateParser.TryParse(headerValue, out DateTimeOffset dateTimeOffset))
+            {
+                return dateTimeOffset.LocalDateTime;
+            }
+            else
+            {
+                throw new ProtocolViolationException(SR.net_baddate);
             }
-#endif
         }
 
         private void SetDateHeaderHelper(string headerName, DateTime dateTime)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
-            {
-#endif
-                if (dateTime == DateTime.MinValue)
-                    SetSpecialHeaders(headerName, null); // remove header
-                else
-                    SetSpecialHeaders(headerName, HttpDateParser.DateToString(dateTime.ToUniversalTime()));
-#if DEBUG
-            }
-#endif
+            if (dateTime == DateTime.MinValue)
+                SetSpecialHeaders(headerName, null); // remove header
+            else
+                SetSpecialHeaders(headerName, HttpDateParser.DateToString(dateTime.ToUniversalTime()));
         }
 
         private bool TryGetHostUri(string hostName, [NotNullWhen(true)] out Uri? hostUri)
index a64a6ca..8024ce1 100644 (file)
@@ -485,140 +485,133 @@ namespace System.Net
         private static void ThreadProc()
         {
             if (NetEventSource.IsEnabled) NetEventSource.Enter(null);
-#if DEBUG
-            DebugThreadTracking.SetThreadSource(ThreadKinds.Timer);
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.System | ThreadKinds.Async))
+
+            // Set this thread as a background thread.  On AppDomain/Process shutdown, the thread will just be killed.
+            Thread.CurrentThread.IsBackground = true;
+
+            // Keep a permanent lock on s_Queues.  This lets for example Shutdown() know when this thread isn't running.
+            lock (s_queues)
             {
-#endif
-                // Set this thread as a background thread.  On AppDomain/Process shutdown, the thread will just be killed.
-                Thread.CurrentThread.IsBackground = true;
+                // If shutdown was recently called, abort here.
+                if (Interlocked.CompareExchange(ref s_threadState, (int)TimerThreadState.Running, (int)TimerThreadState.Running) !=
+                    (int)TimerThreadState.Running)
+                {
+                    return;
+                }
 
-                // Keep a permanent lock on s_Queues.  This lets for example Shutdown() know when this thread isn't running.
-                lock (s_queues)
+                bool running = true;
+                while (running)
                 {
-                    // If shutdown was recently called, abort here.
-                    if (Interlocked.CompareExchange(ref s_threadState, (int)TimerThreadState.Running, (int)TimerThreadState.Running) !=
-                        (int)TimerThreadState.Running)
+                    try
                     {
-                        return;
-                    }
+                        s_threadReadyEvent.Reset();
 
-                    bool running = true;
-                    while (running)
-                    {
-                        try
+                        while (true)
                         {
-                            s_threadReadyEvent.Reset();
-
-                            while (true)
+                            // Copy all the new queues to the real queues.  Since only this thread modifies the real queues, it doesn't have to lock it.
+                            if (s_newQueues.Count > 0)
                             {
-                                // Copy all the new queues to the real queues.  Since only this thread modifies the real queues, it doesn't have to lock it.
-                                if (s_newQueues.Count > 0)
+                                lock (s_newQueues)
                                 {
-                                    lock (s_newQueues)
+                                    for (LinkedListNode<WeakReference>? node = s_newQueues.First; node != null; node = s_newQueues.First)
                                     {
-                                        for (LinkedListNode<WeakReference>? node = s_newQueues.First; node != null; node = s_newQueues.First)
-                                        {
-                                            s_newQueues.Remove(node);
-                                            s_queues.AddLast(node);
-                                        }
+                                        s_newQueues.Remove(node);
+                                        s_queues.AddLast(node);
                                     }
                                 }
+                            }
 
-                                int now = Environment.TickCount;
-                                int nextTick = 0;
-                                bool haveNextTick = false;
-                                for (LinkedListNode<WeakReference>? node = s_queues.First; node != null; /* node = node.Next must be done in the body */)
+                            int now = Environment.TickCount;
+                            int nextTick = 0;
+                            bool haveNextTick = false;
+                            for (LinkedListNode<WeakReference>? node = s_queues.First; node != null; /* node = node.Next must be done in the body */)
+                            {
+                                TimerQueue? queue = (TimerQueue?)node.Value.Target;
+                                if (queue == null)
                                 {
-                                    TimerQueue? queue = (TimerQueue?)node.Value.Target;
-                                    if (queue == null)
-                                    {
-                                        LinkedListNode<WeakReference>? next = node.Next;
-                                        s_queues.Remove(node);
-                                        node = next;
-                                        continue;
-                                    }
-
-                                    // Fire() will always return values that should be interpreted as later than 'now' (that is, even if 'now' is
-                                    // returned, it is 0x100000000 milliseconds in the future).  There's also a chance that Fire() will return a value
-                                    // intended as > 0x100000000 milliseconds from 'now'.  Either case will just cause an extra scan through the timers.
-                                    int nextTickInstance;
-                                    if (queue.Fire(out nextTickInstance) && (!haveNextTick || IsTickBetween(now, nextTick, nextTickInstance)))
-                                    {
-                                        nextTick = nextTickInstance;
-                                        haveNextTick = true;
-                                    }
+                                    LinkedListNode<WeakReference>? next = node.Next;
+                                    s_queues.Remove(node);
+                                    node = next;
+                                    continue;
+                                }
 
-                                    node = node.Next;
+                                // Fire() will always return values that should be interpreted as later than 'now' (that is, even if 'now' is
+                                // returned, it is 0x100000000 milliseconds in the future).  There's also a chance that Fire() will return a value
+                                // intended as > 0x100000000 milliseconds from 'now'.  Either case will just cause an extra scan through the timers.
+                                int nextTickInstance;
+                                if (queue.Fire(out nextTickInstance) && (!haveNextTick || IsTickBetween(now, nextTick, nextTickInstance)))
+                                {
+                                    nextTick = nextTickInstance;
+                                    haveNextTick = true;
                                 }
 
-                                // Figure out how long to wait, taking into account how long the loop took.
-                                // Add 15 ms to compensate for poor TickCount resolution (want to guarantee a firing).
-                                int newNow = Environment.TickCount;
-                                int waitDuration = haveNextTick ?
-                                    (int)(IsTickBetween(now, nextTick, newNow) ?
-                                        Math.Min(unchecked((uint)(nextTick - newNow)), (uint)(int.MaxValue - TickCountResolution)) + TickCountResolution :
-                                        0) :
-                                    ThreadIdleTimeoutMilliseconds;
+                                node = node.Next;
+                            }
 
-                                if (NetEventSource.IsEnabled) NetEventSource.Info(null, $"Waiting for {waitDuration}ms");
+                            // Figure out how long to wait, taking into account how long the loop took.
+                            // Add 15 ms to compensate for poor TickCount resolution (want to guarantee a firing).
+                            int newNow = Environment.TickCount;
+                            int waitDuration = haveNextTick ?
+                                (int)(IsTickBetween(now, nextTick, newNow) ?
+                                    Math.Min(unchecked((uint)(nextTick - newNow)), (uint)(int.MaxValue - TickCountResolution)) + TickCountResolution :
+                                    0) :
+                                ThreadIdleTimeoutMilliseconds;
 
-                                int waitResult = WaitHandle.WaitAny(s_threadEvents, waitDuration, false);
+                            if (NetEventSource.IsEnabled) NetEventSource.Info(null, $"Waiting for {waitDuration}ms");
 
-                                // 0 is s_ThreadShutdownEvent - die.
-                                if (waitResult == 0)
-                                {
-                                    if (NetEventSource.IsEnabled) NetEventSource.Info(null, "Awoke, cause: Shutdown");
-                                    running = false;
-                                    break;
-                                }
+                            int waitResult = WaitHandle.WaitAny(s_threadEvents, waitDuration, false);
+
+                            // 0 is s_ThreadShutdownEvent - die.
+                            if (waitResult == 0)
+                            {
+                                if (NetEventSource.IsEnabled) NetEventSource.Info(null, "Awoke, cause: Shutdown");
+                                running = false;
+                                break;
+                            }
 
-                                if (NetEventSource.IsEnabled) NetEventSource.Info(null, $"Awoke, cause {(waitResult == WaitHandle.WaitTimeout ? "Timeout" : "Prod")}");
+                            if (NetEventSource.IsEnabled) NetEventSource.Info(null, $"Awoke, cause {(waitResult == WaitHandle.WaitTimeout ? "Timeout" : "Prod")}");
 
-                                // If we timed out with nothing to do, shut down.
-                                if (waitResult == WaitHandle.WaitTimeout && !haveNextTick)
+                            // If we timed out with nothing to do, shut down.
+                            if (waitResult == WaitHandle.WaitTimeout && !haveNextTick)
+                            {
+                                Interlocked.CompareExchange(ref s_threadState, (int)TimerThreadState.Idle, (int)TimerThreadState.Running);
+                                // There could have been one more prod between the wait and the exchange.  Check, and abort if necessary.
+                                if (s_threadReadyEvent.WaitOne(0, false))
                                 {
-                                    Interlocked.CompareExchange(ref s_threadState, (int)TimerThreadState.Idle, (int)TimerThreadState.Running);
-                                    // There could have been one more prod between the wait and the exchange.  Check, and abort if necessary.
-                                    if (s_threadReadyEvent.WaitOne(0, false))
+                                    if (Interlocked.CompareExchange(ref s_threadState, (int)TimerThreadState.Running, (int)TimerThreadState.Idle) ==
+                                        (int)TimerThreadState.Idle)
                                     {
-                                        if (Interlocked.CompareExchange(ref s_threadState, (int)TimerThreadState.Running, (int)TimerThreadState.Idle) ==
-                                            (int)TimerThreadState.Idle)
-                                        {
-                                            continue;
-                                        }
+                                        continue;
                                     }
-
-                                    running = false;
-                                    break;
                                 }
+
+                                running = false;
+                                break;
                             }
                         }
-                        catch (Exception exception)
-                        {
-                            if (ExceptionCheck.IsFatal(exception))
-                                throw;
+                    }
+                    catch (Exception exception)
+                    {
+                        if (ExceptionCheck.IsFatal(exception))
+                            throw;
 
-                            if (NetEventSource.IsEnabled) NetEventSource.Error(null, exception);
+                        if (NetEventSource.IsEnabled) NetEventSource.Error(null, exception);
 
-                            // The only options are to continue processing and likely enter an error-loop,
-                            // shut down timers for this AppDomain, or shut down the AppDomain.  Go with shutting
-                            // down the AppDomain in debug, and going into a loop in retail, but try to make the
-                            // loop somewhat slow.  Note that in retail, this can only be triggered by OutOfMemory or StackOverflow,
-                            // or an exception thrown within TimerThread - the rest are caught in Fire().
+                        // The only options are to continue processing and likely enter an error-loop,
+                        // shut down timers for this AppDomain, or shut down the AppDomain.  Go with shutting
+                        // down the AppDomain in debug, and going into a loop in retail, but try to make the
+                        // loop somewhat slow.  Note that in retail, this can only be triggered by OutOfMemory or StackOverflow,
+                        // or an exception thrown within TimerThread - the rest are caught in Fire().
 #if !DEBUG
-                            Thread.Sleep(1000);
+                        Thread.Sleep(1000);
 #else
-                            throw;
+                        throw;
 #endif
-                        }
                     }
                 }
-
-                if (NetEventSource.IsEnabled) NetEventSource.Info(null, "Stop");
-#if DEBUG
             }
-#endif
+
+            if (NetEventSource.IsEnabled) NetEventSource.Info(null, "Stop");
         }
 
         /// <summary>
index 067df9b..f2daece 100644 (file)
@@ -48,8 +48,6 @@
     <Compile Include="System\Security\Authentication\ExtendedProtection\ProtectionScenario.cs" />
     <Compile Include="System\Security\Authentication\ExtendedProtection\ServiceNameCollection.cs" />
     <!-- Logging -->
-    <Compile Include="$(CommonPath)System\Net\Logging\DebugThreadTracking.cs"
-             Link="Common\System\Net\Logging\DebugThreadTracking.cs" />
     <Compile Include="$(CommonPath)System\Net\Logging\NetEventSource.Common.cs"
              Link="Common\System\Net\Logging\NetEventSource.Common.cs" />
     <Compile Include="$(CommonPath)System\Net\InternalException.cs"
index c8c7944..9c8eac2 100644 (file)
@@ -47,31 +47,24 @@ namespace System.Net.Security
 
         protected override void Dispose(bool disposing)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User))
+            try
             {
-#endif
-                try
+                if (disposing)
                 {
-                    if (disposing)
+                    if (_leaveStreamOpen)
                     {
-                        if (_leaveStreamOpen)
-                        {
-                            _innerStream.Flush();
-                        }
-                        else
-                        {
-                            _innerStream.Dispose();
-                        }
+                        _innerStream.Flush();
+                    }
+                    else
+                    {
+                        _innerStream.Dispose();
                     }
                 }
-                finally
-                {
-                    base.Dispose(disposing);
-                }
-#if DEBUG
             }
-#endif
+            finally
+            {
+                base.Dispose(disposing);
+            }
         }
 
         public override ValueTask DisposeAsync()
index 7fdf5ab..0b221f4 100644 (file)
@@ -37,16 +37,9 @@ namespace System.Net.Security
 
         public NegotiateStream(Stream innerStream, bool leaveInnerStreamOpen) : base(innerStream, leaveInnerStreamOpen)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User))
-            {
-#endif
-                _negoState = new NegoState(innerStream);
-                _package = NegoState.DefaultPackage;
-                InitializeStreamPart();
-#if DEBUG
-            }
-#endif
+            _negoState = new NegoState(innerStream);
+            _package = NegoState.DefaultPackage;
+            InitializeStreamPart();
         }
 
         public virtual IAsyncResult BeginAuthenticateAsClient(AsyncCallback? asyncCallback, object? asyncState)
@@ -92,31 +85,17 @@ namespace System.Net.Security
             AsyncCallback? asyncCallback,
             object? asyncState)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
-            {
-#endif
-                _negoState.ValidateCreateContext(_package, false, credential, targetName, binding, requiredProtectionLevel, allowedImpersonationLevel);
+            _negoState.ValidateCreateContext(_package, false, credential, targetName, binding, requiredProtectionLevel, allowedImpersonationLevel);
 
-                LazyAsyncResult result = new LazyAsyncResult(_negoState, asyncState, asyncCallback);
-                _negoState.ProcessAuthentication(result);
+            LazyAsyncResult result = new LazyAsyncResult(_negoState, asyncState, asyncCallback);
+            _negoState.ProcessAuthentication(result);
 
-                return result;
-#if DEBUG
-            }
-#endif
+            return result;
         }
 
         public virtual void EndAuthenticateAsClient(IAsyncResult asyncResult)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User))
-            {
-#endif
-                _negoState.EndProcessAuthentication(asyncResult);
-#if DEBUG
-            }
-#endif
+            _negoState.EndProcessAuthentication(asyncResult);
         }
 
         public virtual void AuthenticateAsServer()
@@ -136,15 +115,8 @@ namespace System.Net.Security
 
         public virtual void AuthenticateAsServer(NetworkCredential credential, ExtendedProtectionPolicy? policy, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel requiredImpersonationLevel)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync))
-            {
-#endif
-                _negoState.ValidateCreateContext(_package, credential, string.Empty, policy, requiredProtectionLevel, requiredImpersonationLevel);
-                _negoState.ProcessAuthentication(null);
-#if DEBUG
-            }
-#endif
+            _negoState.ValidateCreateContext(_package, credential, string.Empty, policy, requiredProtectionLevel, requiredImpersonationLevel);
+            _negoState.ProcessAuthentication(null);
         }
 
         public virtual IAsyncResult BeginAuthenticateAsServer(AsyncCallback? asyncCallback, object? asyncState)
@@ -175,31 +147,17 @@ namespace System.Net.Security
             AsyncCallback? asyncCallback,
             object? asyncState)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
-            {
-#endif
-                _negoState.ValidateCreateContext(_package, credential, string.Empty, policy, requiredProtectionLevel, requiredImpersonationLevel);
+            _negoState.ValidateCreateContext(_package, credential, string.Empty, policy, requiredProtectionLevel, requiredImpersonationLevel);
 
-                LazyAsyncResult result = new LazyAsyncResult(_negoState, asyncState, asyncCallback);
-                _negoState.ProcessAuthentication(result);
+            LazyAsyncResult result = new LazyAsyncResult(_negoState, asyncState, asyncCallback);
+            _negoState.ProcessAuthentication(result);
 
-                return result;
-#if DEBUG
-            }
-#endif
+            return result;
         }
         //
         public virtual void EndAuthenticateAsServer(IAsyncResult asyncResult)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User))
-            {
-#endif
-                _negoState.EndProcessAuthentication(asyncResult);
-#if DEBUG
-            }
-#endif
+            _negoState.EndProcessAuthentication(asyncResult);
         }
 
         public virtual void AuthenticateAsClient()
@@ -226,15 +184,8 @@ namespace System.Net.Security
         public virtual void AuthenticateAsClient(
             NetworkCredential credential, ChannelBinding? binding, string targetName, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel allowedImpersonationLevel)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync))
-            {
-#endif
-                _negoState.ValidateCreateContext(_package, false, credential, targetName, binding, requiredProtectionLevel, allowedImpersonationLevel);
-                _negoState.ProcessAuthentication(null);
-#if DEBUG
-            }
-#endif
+            _negoState.ValidateCreateContext(_package, false, credential, targetName, binding, requiredProtectionLevel, allowedImpersonationLevel);
+            _negoState.ProcessAuthentication(null);
         }
 
         public virtual Task AuthenticateAsClientAsync()
@@ -295,14 +246,7 @@ namespace System.Net.Security
         {
             get
             {
-#if DEBUG
-                using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
-                {
-#endif
-                    return _negoState.IsAuthenticated;
-#if DEBUG
-                }
-#endif
+                return _negoState.IsAuthenticated;
             }
         }
 
@@ -310,14 +254,7 @@ namespace System.Net.Security
         {
             get
             {
-#if DEBUG
-                using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
-                {
-#endif
-                    return _negoState.IsMutuallyAuthenticated;
-#if DEBUG
-                }
-#endif
+                return _negoState.IsMutuallyAuthenticated;
             }
         }
 
@@ -325,14 +262,7 @@ namespace System.Net.Security
         {
             get
             {
-#if DEBUG
-                using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
-                {
-#endif
-                    return _negoState.IsEncrypted;
-#if DEBUG
-                }
-#endif
+                return _negoState.IsEncrypted;
             }
         }
 
@@ -340,14 +270,7 @@ namespace System.Net.Security
         {
             get
             {
-#if DEBUG
-                using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
-                {
-#endif
-                    return _negoState.IsSigned;
-#if DEBUG
-                }
-#endif
+                return _negoState.IsSigned;
             }
         }
 
@@ -355,14 +278,7 @@ namespace System.Net.Security
         {
             get
             {
-#if DEBUG
-                using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
-                {
-#endif
-                    return _negoState.IsServer;
-#if DEBUG
-                }
-#endif
+                return _negoState.IsServer;
             }
         }
 
@@ -370,14 +286,7 @@ namespace System.Net.Security
         {
             get
             {
-#if DEBUG
-                using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
-                {
-#endif
-                    return _negoState.AllowedImpersonation;
-#if DEBUG
-                }
-#endif
+                return _negoState.AllowedImpersonation;
             }
         }
 
@@ -385,20 +294,12 @@ namespace System.Net.Security
         {
             get
             {
-#if DEBUG
-                using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
+                if (_remoteIdentity == null)
                 {
-#endif
-
-                    if (_remoteIdentity == null)
-                    {
-                        _remoteIdentity = _negoState.GetIdentity();
-                    }
-
-                    return _remoteIdentity;
-#if DEBUG
+                    _remoteIdentity = _negoState.GetIdentity();
                 }
-#endif
+
+                return _remoteIdentity;
             }
         }
 
@@ -493,14 +394,7 @@ namespace System.Net.Security
 
         public override void Flush()
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync))
-            {
-#endif
-                InnerStream.Flush();
-#if DEBUG
-            }
-#endif
+            InnerStream.Flush();
         }
 
         public override Task FlushAsync(CancellationToken cancellationToken)
@@ -510,21 +404,14 @@ namespace System.Net.Security
 
         protected override void Dispose(bool disposing)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User))
+            try
             {
-#endif
-                try
-                {
-                    _negoState.Close();
-                }
-                finally
-                {
-                    base.Dispose(disposing);
-                }
-#if DEBUG
+                _negoState.Close();
+            }
+            finally
+            {
+                base.Dispose(disposing);
             }
-#endif
         }
 
         public override async ValueTask DisposeAsync()
@@ -541,183 +428,139 @@ namespace System.Net.Security
 
         public override int Read(byte[] buffer, int offset, int count)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync))
-            {
-#endif
-                _negoState.CheckThrow(true);
+            _negoState.CheckThrow(true);
 
-                if (!_negoState.CanGetSecureStream)
-                {
-                    return InnerStream.Read(buffer, offset, count);
-                }
-
-                return ProcessRead(buffer, offset, count, null);
-#if DEBUG
+            if (!_negoState.CanGetSecureStream)
+            {
+                return InnerStream.Read(buffer, offset, count);
             }
-#endif
+
+            return ProcessRead(buffer, offset, count, null);
         }
 
         public override void Write(byte[] buffer, int offset, int count)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync))
-            {
-#endif
-                _negoState.CheckThrow(true);
+            _negoState.CheckThrow(true);
 
-                if (!_negoState.CanGetSecureStream)
-                {
-                    InnerStream.Write(buffer, offset, count);
-                    return;
-                }
-
-                ProcessWrite(buffer, offset, count, null);
-#if DEBUG
+            if (!_negoState.CanGetSecureStream)
+            {
+                InnerStream.Write(buffer, offset, count);
+                return;
             }
-#endif
+
+            ProcessWrite(buffer, offset, count, null);
         }
 
         public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
-            {
-#endif
-                _negoState.CheckThrow(true);
-
-                if (!_negoState.CanGetSecureStream)
-                {
-                    return TaskToApm.Begin(InnerStream.ReadAsync(buffer, offset, count), asyncCallback, asyncState);
-                }
+            _negoState.CheckThrow(true);
 
-                BufferAsyncResult bufferResult = new BufferAsyncResult(this, buffer, offset, count, asyncState, asyncCallback);
-                AsyncProtocolRequest asyncRequest = new AsyncProtocolRequest(bufferResult);
-                ProcessRead(buffer, offset, count, asyncRequest);
-                return bufferResult;
-#if DEBUG
+            if (!_negoState.CanGetSecureStream)
+            {
+                return TaskToApm.Begin(InnerStream.ReadAsync(buffer, offset, count), asyncCallback, asyncState);
             }
-#endif
+
+            BufferAsyncResult bufferResult = new BufferAsyncResult(this, buffer, offset, count, asyncState, asyncCallback);
+            AsyncProtocolRequest asyncRequest = new AsyncProtocolRequest(bufferResult);
+            ProcessRead(buffer, offset, count, asyncRequest);
+            return bufferResult;
         }
 
         public override int EndRead(IAsyncResult asyncResult)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User))
-            {
-#endif
-                _negoState.CheckThrow(true);
-
-                if (!_negoState.CanGetSecureStream)
-                {
-                    return TaskToApm.End<int>(asyncResult);
-                }
+            _negoState.CheckThrow(true);
 
+            if (!_negoState.CanGetSecureStream)
+            {
+                return TaskToApm.End<int>(asyncResult);
+            }
 
-                if (asyncResult == null)
-                {
-                    throw new ArgumentNullException(nameof(asyncResult));
-                }
+            if (asyncResult == null)
+            {
+                throw new ArgumentNullException(nameof(asyncResult));
+            }
 
-                BufferAsyncResult? bufferResult = asyncResult as BufferAsyncResult;
-                if (bufferResult == null)
-                {
-                    throw new ArgumentException(SR.Format(SR.net_io_async_result, asyncResult.GetType().FullName), nameof(asyncResult));
-                }
+            BufferAsyncResult? bufferResult = asyncResult as BufferAsyncResult;
+            if (bufferResult == null)
+            {
+                throw new ArgumentException(SR.Format(SR.net_io_async_result, asyncResult.GetType().FullName), nameof(asyncResult));
+            }
 
-                if (Interlocked.Exchange(ref _NestedRead, 0) == 0)
-                {
-                    throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, "EndRead"));
-                }
+            if (Interlocked.Exchange(ref _NestedRead, 0) == 0)
+            {
+                throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, "EndRead"));
+            }
 
-                // No "artificial" timeouts implemented so far, InnerStream controls timeout.
-                bufferResult.InternalWaitForCompletion();
+            // No "artificial" timeouts implemented so far, InnerStream controls timeout.
+            bufferResult.InternalWaitForCompletion();
 
-                if (bufferResult.Result is Exception e)
+            if (bufferResult.Result is Exception e)
+            {
+                if (e is IOException)
                 {
-                    if (e is IOException)
-                    {
-                        ExceptionDispatchInfo.Throw(e);
-                    }
-
-                    throw new IOException(SR.net_io_read, e);
+                    ExceptionDispatchInfo.Throw(e);
                 }
 
-                return bufferResult.Int32Result;
-#if DEBUG
+                throw new IOException(SR.net_io_read, e);
             }
-#endif
+
+            return bufferResult.Int32Result;
         }
-        //
-        //
+
         public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
-            {
-#endif
-                _negoState.CheckThrow(true);
+            _negoState.CheckThrow(true);
 
-                if (!_negoState.CanGetSecureStream)
-                {
-                    return TaskToApm.Begin(InnerStream.WriteAsync(buffer, offset, count), asyncCallback, asyncState);
-                }
+            if (!_negoState.CanGetSecureStream)
+            {
+                return TaskToApm.Begin(InnerStream.WriteAsync(buffer, offset, count), asyncCallback, asyncState);
+            }
 
-                BufferAsyncResult bufferResult = new BufferAsyncResult(this, buffer, offset, count, asyncState, asyncCallback);
-                AsyncProtocolRequest asyncRequest = new AsyncProtocolRequest(bufferResult);
+            BufferAsyncResult bufferResult = new BufferAsyncResult(this, buffer, offset, count, asyncState, asyncCallback);
+            AsyncProtocolRequest asyncRequest = new AsyncProtocolRequest(bufferResult);
 
-                ProcessWrite(buffer, offset, count, asyncRequest);
-                return bufferResult;
-#if DEBUG
-            }
-#endif
+            ProcessWrite(buffer, offset, count, asyncRequest);
+            return bufferResult;
         }
 
         public override void EndWrite(IAsyncResult asyncResult)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User))
-            {
-#endif
-                _negoState.CheckThrow(true);
+            _negoState.CheckThrow(true);
 
-                if (!_negoState.CanGetSecureStream)
-                {
-                    TaskToApm.End(asyncResult);
-                    return;
-                }
+            if (!_negoState.CanGetSecureStream)
+            {
+                TaskToApm.End(asyncResult);
+                return;
+            }
 
-                if (asyncResult == null)
-                {
-                    throw new ArgumentNullException(nameof(asyncResult));
-                }
+            if (asyncResult == null)
+            {
+                throw new ArgumentNullException(nameof(asyncResult));
+            }
 
-                BufferAsyncResult? bufferResult = asyncResult as BufferAsyncResult;
-                if (bufferResult == null)
-                {
-                    throw new ArgumentException(SR.Format(SR.net_io_async_result, asyncResult.GetType().FullName), nameof(asyncResult));
-                }
+            BufferAsyncResult? bufferResult = asyncResult as BufferAsyncResult;
+            if (bufferResult == null)
+            {
+                throw new ArgumentException(SR.Format(SR.net_io_async_result, asyncResult.GetType().FullName), nameof(asyncResult));
+            }
 
-                if (Interlocked.Exchange(ref _NestedWrite, 0) == 0)
-                {
-                    throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, "EndWrite"));
-                }
+            if (Interlocked.Exchange(ref _NestedWrite, 0) == 0)
+            {
+                throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, "EndWrite"));
+            }
 
-                // No "artificial" timeouts implemented so far, InnerStream controls timeout.
-                bufferResult.InternalWaitForCompletion();
+            // No "artificial" timeouts implemented so far, InnerStream controls timeout.
+            bufferResult.InternalWaitForCompletion();
 
-                if (bufferResult.Result is Exception e)
+            if (bufferResult.Result is Exception e)
+            {
+                if (e is IOException)
                 {
-                    if (e is IOException)
-                    {
-                        ExceptionDispatchInfo.Throw(e);
-                    }
-
-                    throw new IOException(SR.net_io_write, e);
+                    ExceptionDispatchInfo.Throw(e);
                 }
-#if DEBUG
+
+                throw new IOException(SR.net_io_write, e);
             }
-#endif
         }
     }
 }
index fea68b7..3661f2b 100644 (file)
@@ -51,8 +51,6 @@
     <Compile Include="$(CommonPath)System\IO\StreamHelpers.CopyValidation.cs"
              Link="Common\System\IO\StreamHelpers.CopyValidation.cs" />
     <!-- Logging -->
-    <Compile Include="$(CommonPath)System\Net\Logging\DebugThreadTracking.cs"
-             Link="Common\System\Net\Logging\DebugThreadTracking.cs" />
     <Compile Include="$(CommonPath)System\Net\Logging\NetEventSource.Common.cs"
              Link="Common\System\Net\Logging\NetEventSource.Common.cs" />
     <Compile Include="$(CommonPath)System\Net\InternalException.cs"
index 004c059..a92b87c 100644 (file)
@@ -60,74 +60,66 @@ namespace System.Net.Sockets
 
         private static unsafe void CompletionPortCallback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped)
         {
-#if DEBUG
-            DebugThreadTracking.SetThreadSource(ThreadKinds.CompletionPort);
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.System))
+            BaseOverlappedAsyncResult asyncResult = (BaseOverlappedAsyncResult)ThreadPoolBoundHandle.GetNativeOverlappedState(nativeOverlapped)!;
+
+            if (asyncResult.InternalPeekCompleted)
             {
-#endif
-                BaseOverlappedAsyncResult asyncResult = (BaseOverlappedAsyncResult)ThreadPoolBoundHandle.GetNativeOverlappedState(nativeOverlapped)!;
+                NetEventSource.Fail(null, $"asyncResult.IsCompleted: {asyncResult}");
+            }
+            if (NetEventSource.IsEnabled) NetEventSource.Info(null, $"errorCode:{errorCode} numBytes:{numBytes} nativeOverlapped:{(IntPtr)nativeOverlapped}");
+
+            // Complete the IO and invoke the user's callback.
+            SocketError socketError = (SocketError)errorCode;
 
-                if (asyncResult.InternalPeekCompleted)
+            if (socketError != SocketError.Success && socketError != SocketError.OperationAborted)
+            {
+                // There are cases where passed errorCode does not reflect the details of the underlined socket error.
+                // "So as of today, the key is the difference between WSAECONNRESET and ConnectionAborted,
+                //  .e.g remote party or network causing the connection reset or something on the local host (e.g. closesocket
+                // or receiving data after shutdown (SD_RECV)).  With Winsock/TCP stack rewrite in longhorn, there may
+                // be other differences as well."
+
+                Socket? socket = asyncResult.AsyncObject as Socket;
+                if (socket == null)
                 {
-                    NetEventSource.Fail(null, $"asyncResult.IsCompleted: {asyncResult}");
+                    socketError = SocketError.NotSocket;
                 }
-                if (NetEventSource.IsEnabled) NetEventSource.Info(null, $"errorCode:{errorCode} numBytes:{numBytes} nativeOverlapped:{(IntPtr)nativeOverlapped}");
-
-                // Complete the IO and invoke the user's callback.
-                SocketError socketError = (SocketError)errorCode;
-
-                if (socketError != SocketError.Success && socketError != SocketError.OperationAborted)
+                else if (socket.Disposed)
                 {
-                    // There are cases where passed errorCode does not reflect the details of the underlined socket error.
-                    // "So as of today, the key is the difference between WSAECONNRESET and ConnectionAborted,
-                    //  .e.g remote party or network causing the connection reset or something on the local host (e.g. closesocket
-                    // or receiving data after shutdown (SD_RECV)).  With Winsock/TCP stack rewrite in longhorn, there may
-                    // be other differences as well."
-
-                    Socket? socket = asyncResult.AsyncObject as Socket;
-                    if (socket == null)
-                    {
-                        socketError = SocketError.NotSocket;
-                    }
-                    else if (socket.Disposed)
-                    {
-                        socketError = SocketError.OperationAborted;
-                    }
-                    else
+                    socketError = SocketError.OperationAborted;
+                }
+                else
+                {
+                    try
                     {
-                        try
+                        // The async IO completed with a failure.
+                        // Here we need to call WSAGetOverlappedResult() just so GetLastSocketError() will return the correct error.
+                        SocketFlags ignore;
+                        bool success = Interop.Winsock.WSAGetOverlappedResult(
+                            socket.SafeHandle,
+                            nativeOverlapped,
+                            out numBytes,
+                            false,
+                            out ignore);
+                        if (!success)
                         {
-                            // The async IO completed with a failure.
-                            // Here we need to call WSAGetOverlappedResult() just so GetLastSocketError() will return the correct error.
-                            SocketFlags ignore;
-                            bool success = Interop.Winsock.WSAGetOverlappedResult(
-                                socket.SafeHandle,
-                                nativeOverlapped,
-                                out numBytes,
-                                false,
-                                out ignore);
-                            if (!success)
-                            {
-                                socketError = SocketPal.GetLastSocketError();
-                            }
-                            if (success)
-                            {
-                                NetEventSource.Fail(asyncResult, $"Unexpectedly succeeded. errorCode:{errorCode} numBytes:{numBytes}");
-                            }
+                            socketError = SocketPal.GetLastSocketError();
                         }
-                        catch (ObjectDisposedException)
+                        if (success)
                         {
-                            // Disposed check above does not always work since this code is subject to race conditions
-                            socketError = SocketError.OperationAborted;
+                            NetEventSource.Fail(asyncResult, $"Unexpectedly succeeded. errorCode:{errorCode} numBytes:{numBytes}");
                         }
                     }
+                    catch (ObjectDisposedException)
+                    {
+                        // Disposed check above does not always work since this code is subject to race conditions
+                        socketError = SocketError.OperationAborted;
+                    }
                 }
-
-                // Set results and invoke callback
-                asyncResult.CompletionCallback((int)numBytes, socketError);
-#if DEBUG
             }
-#endif
+
+            // Set results and invoke callback
+            asyncResult.CompletionCallback((int)numBytes, socketError);
         }
 
         // Called either synchronously from SocketPal async routines or asynchronously via CompletionPortCallback above.
index 772ad52..077ad2d 100644 (file)
@@ -41,51 +41,44 @@ namespace System.Net.Sockets
 
         public NetworkStream(Socket socket, FileAccess access, bool ownsSocket)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User))
+            if (socket == null)
             {
-#endif
-                if (socket == null)
-                {
-                    throw new ArgumentNullException(nameof(socket));
-                }
-                if (!socket.Blocking)
-                {
-                    // Stream.Read*/Write* are incompatible with the semantics of non-blocking sockets, and
-                    // allowing non-blocking sockets could result in non-deterministic failures from those
-                    // operations. A developer that requires using NetworkStream with a non-blocking socket can
-                    // temporarily flip Socket.Blocking as a workaround.
-                    throw new IOException(SR.net_sockets_blocking);
-                }
-                if (!socket.Connected)
-                {
-                    throw new IOException(SR.net_notconnected);
-                }
-                if (socket.SocketType != SocketType.Stream)
-                {
-                    throw new IOException(SR.net_notstream);
-                }
+                throw new ArgumentNullException(nameof(socket));
+            }
+            if (!socket.Blocking)
+            {
+                // Stream.Read*/Write* are incompatible with the semantics of non-blocking sockets, and
+                // allowing non-blocking sockets could result in non-deterministic failures from those
+                // operations. A developer that requires using NetworkStream with a non-blocking socket can
+                // temporarily flip Socket.Blocking as a workaround.
+                throw new IOException(SR.net_sockets_blocking);
+            }
+            if (!socket.Connected)
+            {
+                throw new IOException(SR.net_notconnected);
+            }
+            if (socket.SocketType != SocketType.Stream)
+            {
+                throw new IOException(SR.net_notstream);
+            }
 
-                _streamSocket = socket;
-                _ownsSocket = ownsSocket;
+            _streamSocket = socket;
+            _ownsSocket = ownsSocket;
 
-                switch (access)
-                {
-                    case FileAccess.Read:
-                        _readable = true;
-                        break;
-                    case FileAccess.Write:
-                        _writeable = true;
-                        break;
-                    case FileAccess.ReadWrite:
-                    default: // assume FileAccess.ReadWrite
-                        _readable = true;
-                        _writeable = true;
-                        break;
-                }
-#if DEBUG
+            switch (access)
+            {
+                case FileAccess.Read:
+                    _readable = true;
+                    break;
+                case FileAccess.Write:
+                    _writeable = true;
+                    break;
+                case FileAccess.ReadWrite:
+                default: // assume FileAccess.ReadWrite
+                    _readable = true;
+                    _writeable = true;
+                    break;
             }
-#endif
         }
 
         public Socket Socket => _streamSocket;
@@ -124,34 +117,20 @@ namespace System.Net.Sockets
         {
             get
             {
-#if DEBUG
-                using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
+                int timeout = (int)_streamSocket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout)!;
+                if (timeout == 0)
                 {
-#endif
-                    int timeout = (int)_streamSocket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout)!;
-                    if (timeout == 0)
-                    {
-                        return -1;
-                    }
-                    return timeout;
-#if DEBUG
+                    return -1;
                 }
-#endif
+                return timeout;
             }
             set
             {
-#if DEBUG
-                using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
+                if (value <= 0 && value != System.Threading.Timeout.Infinite)
                 {
-#endif
-                    if (value <= 0 && value != System.Threading.Timeout.Infinite)
-                    {
-                        throw new ArgumentOutOfRangeException(nameof(value), SR.net_io_timeout_use_gt_zero);
-                    }
-                    SetSocketTimeoutOption(SocketShutdown.Receive, value, false);
-#if DEBUG
+                    throw new ArgumentOutOfRangeException(nameof(value), SR.net_io_timeout_use_gt_zero);
                 }
-#endif
+                SetSocketTimeoutOption(SocketShutdown.Receive, value, false);
             }
         }
 
@@ -161,34 +140,20 @@ namespace System.Net.Sockets
         {
             get
             {
-#if DEBUG
-                using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
+                int timeout = (int)_streamSocket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout)!;
+                if (timeout == 0)
                 {
-#endif
-                    int timeout = (int)_streamSocket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout)!;
-                    if (timeout == 0)
-                    {
-                        return -1;
-                    }
-                    return timeout;
-#if DEBUG
+                    return -1;
                 }
-#endif
+                return timeout;
             }
             set
             {
-#if DEBUG
-                using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
+                if (value <= 0 && value != System.Threading.Timeout.Infinite)
                 {
-#endif
-                    if (value <= 0 && value != System.Threading.Timeout.Infinite)
-                    {
-                        throw new ArgumentOutOfRangeException(nameof(value), SR.net_io_timeout_use_gt_zero);
-                    }
-                    SetSocketTimeoutOption(SocketShutdown.Send, value, false);
-#if DEBUG
+                    throw new ArgumentOutOfRangeException(nameof(value), SR.net_io_timeout_use_gt_zero);
                 }
-#endif
+                SetSocketTimeoutOption(SocketShutdown.Send, value, false);
             }
         }
 
@@ -198,18 +163,11 @@ namespace System.Net.Sockets
         {
             get
             {
-#if DEBUG
-                using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
-                {
-#endif
-                    ThrowIfDisposed();
+                ThrowIfDisposed();
 
-                    // Ask the socket how many bytes are available. If it's
-                    // not zero, return true.
-                    return _streamSocket.Available != 0;
-#if DEBUG
-                }
-#endif
+                // Ask the socket how many bytes are available. If it's
+                // not zero, return true.
+                return _streamSocket.Available != 0;
             }
         }
 
@@ -259,44 +217,37 @@ namespace System.Net.Sockets
         //     Number of bytes we read, or 0 if the socket is closed.
         public override int Read(byte[] buffer, int offset, int size)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync))
+            bool canRead = CanRead;  // Prevent race with Dispose.
+            ThrowIfDisposed();
+            if (!canRead)
             {
-#endif
-                bool canRead = CanRead;  // Prevent race with Dispose.
-                ThrowIfDisposed();
-                if (!canRead)
-                {
-                    throw new InvalidOperationException(SR.net_writeonlystream);
-                }
+                throw new InvalidOperationException(SR.net_writeonlystream);
+            }
 
-                // Validate input parameters.
-                if (buffer == null)
-                {
-                    throw new ArgumentNullException(nameof(buffer));
-                }
-                if ((uint)offset > buffer.Length)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(offset));
-                }
-                if ((uint)size > buffer.Length - offset)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(size));
-                }
+            // Validate input parameters.
+            if (buffer == null)
+            {
+                throw new ArgumentNullException(nameof(buffer));
+            }
+            if ((uint)offset > buffer.Length)
+            {
+                throw new ArgumentOutOfRangeException(nameof(offset));
+            }
+            if ((uint)size > buffer.Length - offset)
+            {
+                throw new ArgumentOutOfRangeException(nameof(size));
+            }
 
-                try
-                {
-                    return _streamSocket.Receive(buffer, offset, size, 0);
-                }
-                catch (Exception exception) when (!(exception is OutOfMemoryException))
-                {
-                    // Some sort of error occurred on the socket call,
-                    // set the SocketException as InnerException and throw.
-                    throw new IOException(SR.Format(SR.net_io_readfailure, exception.Message), exception);
-                }
-#if DEBUG
+            try
+            {
+                return _streamSocket.Receive(buffer, offset, size, 0);
+            }
+            catch (Exception exception) when (!(exception is OutOfMemoryException))
+            {
+                // Some sort of error occurred on the socket call,
+                // set the SocketException as InnerException and throw.
+                throw new IOException(SR.Format(SR.net_io_readfailure, exception.Message), exception);
             }
-#endif
         }
 
         public override int Read(Span<byte> buffer)
@@ -345,46 +296,39 @@ namespace System.Net.Sockets
         //     way to indicate an error.
         public override void Write(byte[] buffer, int offset, int size)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync))
+            bool canWrite = CanWrite; // Prevent race with Dispose.
+            ThrowIfDisposed();
+            if (!canWrite)
             {
-#endif
-                bool canWrite = CanWrite; // Prevent race with Dispose.
-                ThrowIfDisposed();
-                if (!canWrite)
-                {
-                    throw new InvalidOperationException(SR.net_readonlystream);
-                }
+                throw new InvalidOperationException(SR.net_readonlystream);
+            }
 
-                // Validate input parameters.
-                if (buffer == null)
-                {
-                    throw new ArgumentNullException(nameof(buffer));
-                }
-                if ((uint)offset > buffer.Length)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(offset));
-                }
-                if ((uint)size > buffer.Length - offset)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(size));
-                }
+            // Validate input parameters.
+            if (buffer == null)
+            {
+                throw new ArgumentNullException(nameof(buffer));
+            }
+            if ((uint)offset > buffer.Length)
+            {
+                throw new ArgumentOutOfRangeException(nameof(offset));
+            }
+            if ((uint)size > buffer.Length - offset)
+            {
+                throw new ArgumentOutOfRangeException(nameof(size));
+            }
 
-                try
-                {
-                    // Since the socket is in blocking mode this will always complete
-                    // after ALL the requested number of bytes was transferred.
-                    _streamSocket.Send(buffer, offset, size, SocketFlags.None);
-                }
-                catch (Exception exception) when (!(exception is OutOfMemoryException))
-                {
-                    // Some sort of error occurred on the socket call,
-                    // set the SocketException as InnerException and throw.
-                    throw new IOException(SR.Format(SR.net_io_writefailure, exception.Message), exception);
-                }
-#if DEBUG
+            try
+            {
+                // Since the socket is in blocking mode this will always complete
+                // after ALL the requested number of bytes was transferred.
+                _streamSocket.Send(buffer, offset, size, SocketFlags.None);
+            }
+            catch (Exception exception) when (!(exception is OutOfMemoryException))
+            {
+                // Some sort of error occurred on the socket call,
+                // set the SocketException as InnerException and throw.
+                throw new IOException(SR.Format(SR.net_io_writefailure, exception.Message), exception);
             }
-#endif
         }
 
         public override void Write(ReadOnlySpan<byte> buffer)
@@ -416,61 +360,42 @@ namespace System.Net.Sockets
 
         public void Close(int timeout)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync))
+            if (timeout < -1)
             {
-#endif
-                if (timeout < -1)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(timeout));
-                }
-                _closeTimeout = timeout;
-                Dispose();
-#if DEBUG
+                throw new ArgumentOutOfRangeException(nameof(timeout));
             }
-#endif
+            _closeTimeout = timeout;
+            Dispose();
         }
         private volatile bool _disposed = false;
         protected override void Dispose(bool disposing)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User))
+            // Mark this as disposed before changing anything else.
+            bool disposed = _disposed;
+            _disposed = true;
+            if (!disposed && disposing)
             {
-#endif
-                // Mark this as disposed before changing anything else.
-                bool disposed = _disposed;
-                _disposed = true;
-                if (!disposed && disposing)
+                // The only resource we need to free is the network stream, since this
+                // is based on the client socket, closing the stream will cause us
+                // to flush the data to the network, close the stream and (in the
+                // NetoworkStream code) close the socket as well.
+                _readable = false;
+                _writeable = false;
+                if (_ownsSocket)
                 {
-                    // The only resource we need to free is the network stream, since this
-                    // is based on the client socket, closing the stream will cause us
-                    // to flush the data to the network, close the stream and (in the
-                    // NetoworkStream code) close the socket as well.
-                    _readable = false;
-                    _writeable = false;
-                    if (_ownsSocket)
-                    {
-                        // If we own the Socket (false by default), close it
-                        // ignoring possible exceptions (eg: the user told us
-                        // that we own the Socket but it closed at some point of time,
-                        // here we would get an ObjectDisposedException)
-                        _streamSocket.InternalShutdown(SocketShutdown.Both);
-                        _streamSocket.Close(_closeTimeout);
-                    }
+                    // If we own the Socket (false by default), close it
+                    // ignoring possible exceptions (eg: the user told us
+                    // that we own the Socket but it closed at some point of time,
+                    // here we would get an ObjectDisposedException)
+                    _streamSocket.InternalShutdown(SocketShutdown.Both);
+                    _streamSocket.Close(_closeTimeout);
                 }
-#if DEBUG
             }
-#endif
+
             base.Dispose(disposing);
         }
 
-        ~NetworkStream()
-        {
-#if DEBUG
-            DebugThreadTracking.SetThreadSource(ThreadKinds.Finalization);
-#endif
-            Dispose(false);
-        }
+        ~NetworkStream() => Dispose(false);
 
         // BeginRead - provide async read functionality.
         //
@@ -488,50 +413,43 @@ namespace System.Net.Sockets
         //     An IASyncResult, representing the read.
         public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback? callback, object? state)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
+            bool canRead = CanRead; // Prevent race with Dispose.
+            ThrowIfDisposed();
+            if (!canRead)
             {
-#endif
-                bool canRead = CanRead; // Prevent race with Dispose.
-                ThrowIfDisposed();
-                if (!canRead)
-                {
-                    throw new InvalidOperationException(SR.net_writeonlystream);
-                }
+                throw new InvalidOperationException(SR.net_writeonlystream);
+            }
 
-                // Validate input parameters.
-                if (buffer == null)
-                {
-                    throw new ArgumentNullException(nameof(buffer));
-                }
-                if ((uint)offset > buffer.Length)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(offset));
-                }
-                if ((uint)size > buffer.Length - offset)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(size));
-                }
+            // Validate input parameters.
+            if (buffer == null)
+            {
+                throw new ArgumentNullException(nameof(buffer));
+            }
+            if ((uint)offset > buffer.Length)
+            {
+                throw new ArgumentOutOfRangeException(nameof(offset));
+            }
+            if ((uint)size > buffer.Length - offset)
+            {
+                throw new ArgumentOutOfRangeException(nameof(size));
+            }
 
-                try
-                {
-                    return _streamSocket.BeginReceive(
-                            buffer,
-                            offset,
-                            size,
-                            SocketFlags.None,
-                            callback,
-                            state);
-                }
-                catch (Exception exception) when (!(exception is OutOfMemoryException))
-                {
-                    // Some sort of error occurred on the socket call,
-                    // set the SocketException as InnerException and throw.
-                    throw new IOException(SR.Format(SR.net_io_readfailure, exception.Message), exception);
-                }
-#if DEBUG
+            try
+            {
+                return _streamSocket.BeginReceive(
+                        buffer,
+                        offset,
+                        size,
+                        SocketFlags.None,
+                        callback,
+                        state);
+            }
+            catch (Exception exception) when (!(exception is OutOfMemoryException))
+            {
+                // Some sort of error occurred on the socket call,
+                // set the SocketException as InnerException and throw.
+                throw new IOException(SR.Format(SR.net_io_readfailure, exception.Message), exception);
             }
-#endif
         }
 
         // EndRead - handle the end of an async read.
@@ -544,31 +462,24 @@ namespace System.Net.Sockets
         //     The number of bytes read. May throw an exception.
         public override int EndRead(IAsyncResult asyncResult)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User))
-            {
-#endif
-                ThrowIfDisposed();
+            ThrowIfDisposed();
 
-                // Validate input parameters.
-                if (asyncResult == null)
-                {
-                    throw new ArgumentNullException(nameof(asyncResult));
-                }
+            // Validate input parameters.
+            if (asyncResult == null)
+            {
+                throw new ArgumentNullException(nameof(asyncResult));
+            }
 
-                try
-                {
-                    return _streamSocket.EndReceive(asyncResult);
-                }
-                catch (Exception exception) when (!(exception is OutOfMemoryException))
-                {
-                    // Some sort of error occurred on the socket call,
-                    // set the SocketException as InnerException and throw.
-                    throw new IOException(SR.Format(SR.net_io_readfailure, exception.Message), exception);
-                }
-#if DEBUG
+            try
+            {
+                return _streamSocket.EndReceive(asyncResult);
+            }
+            catch (Exception exception) when (!(exception is OutOfMemoryException))
+            {
+                // Some sort of error occurred on the socket call,
+                // set the SocketException as InnerException and throw.
+                throw new IOException(SR.Format(SR.net_io_readfailure, exception.Message), exception);
             }
-#endif
         }
 
         // BeginWrite - provide async write functionality.
@@ -587,51 +498,44 @@ namespace System.Net.Sockets
         //     An IASyncResult, representing the write.
         public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback? callback, object? state)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
+            bool canWrite = CanWrite; // Prevent race with Dispose.
+            ThrowIfDisposed();
+            if (!canWrite)
             {
-#endif
-                bool canWrite = CanWrite; // Prevent race with Dispose.
-                ThrowIfDisposed();
-                if (!canWrite)
-                {
-                    throw new InvalidOperationException(SR.net_readonlystream);
-                }
+                throw new InvalidOperationException(SR.net_readonlystream);
+            }
 
-                // Validate input parameters.
-                if (buffer == null)
-                {
-                    throw new ArgumentNullException(nameof(buffer));
-                }
-                if ((uint)offset > buffer.Length)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(offset));
-                }
-                if ((uint)size > buffer.Length - offset)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(size));
-                }
+            // Validate input parameters.
+            if (buffer == null)
+            {
+                throw new ArgumentNullException(nameof(buffer));
+            }
+            if ((uint)offset > buffer.Length)
+            {
+                throw new ArgumentOutOfRangeException(nameof(offset));
+            }
+            if ((uint)size > buffer.Length - offset)
+            {
+                throw new ArgumentOutOfRangeException(nameof(size));
+            }
 
-                try
-                {
-                    // Call BeginSend on the Socket.
-                    return _streamSocket.BeginSend(
-                            buffer,
-                            offset,
-                            size,
-                            SocketFlags.None,
-                            callback,
-                            state);
-                }
-                catch (Exception exception) when (!(exception is OutOfMemoryException))
-                {
-                    // Some sort of error occurred on the socket call,
-                    // set the SocketException as InnerException and throw.
-                    throw new IOException(SR.Format(SR.net_io_writefailure, exception.Message), exception);
-                }
-#if DEBUG
+            try
+            {
+                // Call BeginSend on the Socket.
+                return _streamSocket.BeginSend(
+                        buffer,
+                        offset,
+                        size,
+                        SocketFlags.None,
+                        callback,
+                        state);
+            }
+            catch (Exception exception) when (!(exception is OutOfMemoryException))
+            {
+                // Some sort of error occurred on the socket call,
+                // set the SocketException as InnerException and throw.
+                throw new IOException(SR.Format(SR.net_io_writefailure, exception.Message), exception);
             }
-#endif
         }
 
         // Handle the end of an asynchronous write.
@@ -640,31 +544,24 @@ namespace System.Net.Sockets
         // Returns:  The number of bytes read. May throw an exception.
         public override void EndWrite(IAsyncResult asyncResult)
         {
-#if DEBUG
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.User))
-            {
-#endif
-                ThrowIfDisposed();
+            ThrowIfDisposed();
 
-                // Validate input parameters.
-                if (asyncResult == null)
-                {
-                    throw new ArgumentNullException(nameof(asyncResult));
-                }
+            // Validate input parameters.
+            if (asyncResult == null)
+            {
+                throw new ArgumentNullException(nameof(asyncResult));
+            }
 
-                try
-                {
-                    _streamSocket.EndSend(asyncResult);
-                }
-                catch (Exception exception) when (!(exception is OutOfMemoryException))
-                {
-                    // Some sort of error occurred on the socket call,
-                    // set the SocketException as InnerException and throw.
-                    throw new IOException(SR.Format(SR.net_io_writefailure, exception.Message), exception);
-                }
-#if DEBUG
+            try
+            {
+                _streamSocket.EndSend(asyncResult);
+            }
+            catch (Exception exception) when (!(exception is OutOfMemoryException))
+            {
+                // Some sort of error occurred on the socket call,
+                // set the SocketException as InnerException and throw.
+                throw new IOException(SR.Format(SR.net_io_writefailure, exception.Message), exception);
             }
-#endif
         }
 
         // ReadAsync - provide async read functionality.
index 9295802..71480cf 100644 (file)
@@ -427,18 +427,7 @@ namespace System.Net.Sockets
 
         public void Dispose() => Dispose(true);
 
-        ~TcpClient()
-        {
-#if DEBUG
-            DebugThreadTracking.SetThreadSource(ThreadKinds.Finalization);
-            using (DebugThreadTracking.SetThreadKind(ThreadKinds.System | ThreadKinds.Async))
-            {
-#endif
-                Dispose(false);
-#if DEBUG
-            }
-#endif
-        }
+        ~TcpClient() => Dispose(false);
 
         // Gets or sets the size of the receive buffer in bytes.
         public int ReceiveBufferSize