Move some Task related files to shared CoreLib partition (dotnet/coreclr#21650)
authorJan Kotas <jkotas@microsoft.com>
Sat, 22 Dec 2018 18:01:00 +0000 (10:01 -0800)
committerGitHub <noreply@github.com>
Sat, 22 Dec 2018 18:01:00 +0000 (10:01 -0800)
Commit migrated from https://github.com/dotnet/coreclr/commit/dc3f080b89b7d3c85afdb8b6d2b9086363c48c14

src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj
src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
src/libraries/System.Private.CoreLib/src/System/Threading/CancellationTokenRegistration.cs [moved from src/coreclr/src/System.Private.CoreLib/src/System/Threading/CancellationTokenRegistration.cs with 97% similarity]
src/libraries/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs [moved from src/coreclr/src/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs with 99% similarity]
src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Future.cs [moved from src/coreclr/src/System.Private.CoreLib/src/System/Threading/Tasks/future.cs with 99% similarity]
src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/ProducerConsumerQueues.cs [moved from src/coreclr/src/System.Private.CoreLib/src/System/Threading/Tasks/ProducerConsumerQueues.cs with 100% similarity]
src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskExceptionHolder.cs [moved from src/coreclr/src/System.Private.CoreLib/src/System/Threading/Tasks/TaskExceptionHolder.cs with 86% similarity]
src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskScheduler.cs [moved from src/coreclr/src/System.Private.CoreLib/src/System/Threading/Tasks/TaskScheduler.cs with 95% similarity]
src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs [moved from src/coreclr/src/System.Private.CoreLib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs with 97% similarity]

index 126c626..18de69b 100644 (file)
     <Compile Include="$(BclSourcesRoot)\System\Text\EncodingTable.cs" Condition="'$(FeatureCoreFxGlobalization)' != 'true'" />
     <Compile Include="$(BclSourcesRoot)\System\Text\EncodingTable.Unix.cs" Condition="'$(FeatureCoreFxGlobalization)' == 'true'" />
     <Compile Include="$(BclSourcesRoot)\System\Text\StringBuilder.CoreCLR.cs" />
-    <Compile Include="$(BclSourcesRoot)\System\Threading\CancellationTokenRegistration.cs" />
-    <Compile Include="$(BclSourcesRoot)\System\Threading\CancellationTokenSource.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Threading\ClrThreadPoolBoundHandle.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Threading\ClrThreadPoolBoundHandleOverlapped.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Threading\ClrThreadPoolPreAllocatedOverlapped.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Threading\Overlapped.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Threading\SynchronizationContext.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\AsyncCausalityTracer.cs" />
-    <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\future.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\FutureFactory.cs" />
-    <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\ProducerConsumerQueues.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\Task.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskContinuation.cs" />
-    <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskExceptionHolder.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskFactory.cs" />
-    <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskScheduler.cs" />
-    <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\ThreadPoolTaskScheduler.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\TPLETWProvider.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Threading\Thread.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Threading\ThreadPool.cs" />
index 397853e..96c5b52 100644 (file)
     <Compile Include="$(MSBuildThisFileDirectory)System\Threading\AsyncLocal.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Threading\AutoResetEvent.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Threading\CancellationToken.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)System\Threading\CancellationTokenRegistration.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)System\Threading\CancellationTokenSource.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Threading\DeferredDisposableLifetime.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Threading\EventResetMode.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Threading\EventWaitHandle.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Threading\SynchronizationLockException.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Threading\ThreadLocal.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Threading\Tasks\ConcurrentExclusiveSchedulerPair.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)System\Threading\Tasks\Future.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)System\Threading\Tasks\ProducerConsumerQueues.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Threading\Tasks\TaskCanceledException.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Threading\Tasks\TaskCompletionSource.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)System\Threading\Tasks\TaskExceptionHolder.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Threading\Tasks\TaskExtensions.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Threading\Tasks\TaskToApm.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)System\Threading\Tasks\TaskScheduler.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Threading\Tasks\TaskSchedulerException.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)System\Threading\Tasks\ThreadPoolTaskScheduler.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Threading\Tasks\ValueTask.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Threading\Tasks\Sources\ManualResetValueTaskSourceCore.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Threading\Tasks\Sources\IValueTaskSource.cs" />
@@ -93,7 +93,7 @@ namespace System.Threading
             CancellationTokenSource source = _node.Partition.Source;
             if (source.IsCancellationRequested && // Running callbacks has commenced.
                 !source.IsCancellationCompleted && // Running callbacks hasn't finished.
-                source.ThreadIDExecutingCallbacks != Thread.CurrentThread.ManagedThreadId) // The executing thread ID is not this thread's ID.
+                source.ThreadIDExecutingCallbacks != Environment.CurrentManagedThreadId) // The executing thread ID is not this thread's ID.
             {
                 // Callback execution is in progress, the executing thread is different from this thread and has taken the callback for execution
                 // so observe and wait until this target callback is no longer the executing callback.
@@ -108,7 +108,7 @@ namespace System.Threading
             CancellationTokenSource source = _node.Partition.Source;
             if (source.IsCancellationRequested && // Running callbacks has commenced.
                 !source.IsCancellationCompleted && // Running callbacks hasn't finished.
-                source.ThreadIDExecutingCallbacks != Thread.CurrentThread.ManagedThreadId) // The executing thread ID is not this thread's ID.
+                source.ThreadIDExecutingCallbacks != Environment.CurrentManagedThreadId) // The executing thread ID is not this thread's ID.
             {
                 // Callback execution is in progress, the executing thread is different from this thread and has taken the callback for execution
                 // so get a task that'll complete when this target callback is no longer the executing callback.
@@ -595,7 +595,7 @@ namespace System.Threading
             Debug.Assert(IsCancellationRequested, "ExecuteCallbackHandlers should only be called after setting IsCancellationRequested->true");
 
             // Record the threadID being used for running the callbacks.
-            ThreadIDExecutingCallbacks = Thread.CurrentThread.ManagedThreadId;
+            ThreadIDExecutingCallbacks = Environment.CurrentManagedThreadId;
 
             // If there are no callbacks to run, we can safely exit.  Any race conditions to lazy initialize it
             // will see IsCancellationRequested and will then run the callback themselves.
@@ -669,10 +669,10 @@ namespace System.Threading
                                 node.SynchronizationContext.Send(s =>
                                 {
                                     var n = (CallbackNode)s;
-                                    n.Partition.Source.ThreadIDExecutingCallbacks = Thread.CurrentThread.ManagedThreadId;
+                                    n.Partition.Source.ThreadIDExecutingCallbacks = Environment.CurrentManagedThreadId;
                                     n.ExecuteCallback();
                                 }, node);
-                                ThreadIDExecutingCallbacks = Thread.CurrentThread.ManagedThreadId; // above may have altered ThreadIDExecutingCallbacks, so reset it
+                                ThreadIDExecutingCallbacks = Environment.CurrentManagedThreadId; // above may have altered ThreadIDExecutingCallbacks, so reset it
                             }
                             else
                             {
 //
 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 
-using System;
 using System.Collections.Generic;
-using System.Runtime;
+using System.Diagnostics;
 using System.Runtime.CompilerServices;
 using System.Runtime.ExceptionServices;
-using System.Security;
-using System.Threading;
-using System.Diagnostics;
 
 // Disable the "reference to volatile field not treated as volatile" error.
 #pragma warning disable 0420
@@ -57,34 +57,8 @@ namespace System.Threading.Tasks
         /// </summary>
         ~TaskExceptionHolder()
         {
-            // Raise unhandled exceptions only when we know that neither the process or nor the appdomain is being torn down.
-            // We need to do this filtering because all TaskExceptionHolders will be finalized during shutdown or unload
-            // regardles of reachability of the task (i.e. even if the user code was about to observe the task's exception),
-            // which can otherwise lead to spurious crashes during shutdown.
-            if (m_faultExceptions != null && !m_isHandled && !Environment.HasShutdownStarted)
+            if (m_faultExceptions != null && !m_isHandled)
             {
-                // We don't want to crash the finalizer thread if any ThreadAbortExceptions 
-                // occur in the list or in any nested AggregateExceptions.  
-                // (Don't rethrow ThreadAbortExceptions.)
-                foreach (ExceptionDispatchInfo edi in m_faultExceptions)
-                {
-                    var exp = edi.SourceException;
-                    AggregateException aggExp = exp as AggregateException;
-                    if (aggExp != null)
-                    {
-                        AggregateException flattenedAggExp = aggExp.Flatten();
-                        foreach (Exception innerExp in flattenedAggExp.InnerExceptions)
-                        {
-                            if (innerExp is ThreadAbortException)
-                                return;
-                        }
-                    }
-                    else if (exp is ThreadAbortException)
-                    {
-                        return;
-                    }
-                }
-
                 // We will only propagate if this is truly unhandled. The reason this could
                 // ever occur is somewhat subtle: if a Task's exceptions are observed in some
                 // other finalizer, and the Task was finalized before the holder, the holder
@@ -239,25 +213,8 @@ namespace System.Threading.Tasks
                 }
             }
 
-
-            // If all of the exceptions are ThreadAbortExceptions and/or
-            // AppDomainUnloadExceptions, we do not want the finalization
-            // probe to propagate them, so we consider the holder to be
-            // handled.  If a subsequent exception comes in of a different
-            // kind, we will reactivate the holder.
-            for (int i = 0; i < exceptions.Count; i++)
-            {
-                var t = exceptions[i].SourceException.GetType();
-                if (t != typeof(ThreadAbortException))
-                {
-                    MarkAsUnhandled();
-                    break;
-                }
-                else if (i == exceptions.Count - 1)
-                {
-                    MarkAsHandled(false);
-                }
-            }
+            if (exceptions.Count > 0)
+                MarkAsUnhandled();
         }
 
         /// <summary>
 // Disable the "reference to volatile field not treated as volatile" error.
 #pragma warning disable 0420
 
-using System;
 using System.Collections.Generic;
-using System.Globalization;
-using System.Threading;
-using System.Security;
-using System.Collections.Concurrent;
 using System.Diagnostics;
 using System.Runtime.CompilerServices;
 
@@ -202,10 +197,12 @@ namespace System.Threading.Tasks
             bool bInlined = false;
             try
             {
+#if CORECLR
                 if (TplEtwProvider.Log.IsEnabled())
                 {
                     task.FireTaskScheduledIfNeeded(this);
                 }
+#endif
                 bInlined = TryExecuteTaskInline(task, taskWasPreviouslyQueued);
             }
             finally
@@ -258,10 +255,12 @@ namespace System.Threading.Tasks
         {
             Debug.Assert(task != null);
 
+#if CORECLR
             if (TplEtwProvider.Log.IsEnabled())
             {
                 task.FireTaskScheduledIfNeeded(this);
             }
+#endif
 
             this.QueueTask(task);
         }
@@ -296,6 +295,7 @@ namespace System.Threading.Tasks
         /// </summary>
         protected TaskScheduler()
         {
+#if CORECLR // Debugger support
             // Register the scheduler in the active scheduler list.  This is only relevant when debugging, 
             // so we only pay the cost if the debugger is attached when the scheduler is created.  This
             // means that the internal TaskScheduler.GetTaskSchedulersForDebugger() will only include
@@ -304,6 +304,7 @@ namespace System.Threading.Tasks
             {
                 AddToActiveTaskSchedulers();
             }
+#endif
         }
 
         /// <summary>Adds this scheduler ot the active schedulers tracking collection for debugging purposes.</summary>
@@ -453,9 +454,6 @@ namespace System.Threading.Tasks
         // Events
         //
 
-        private static EventHandler<UnobservedTaskExceptionEventArgs> _unobservedTaskException;
-        private static readonly object _unobservedTaskExceptionLockObject = new object();
-
         /// <summary>
         /// Occurs when a faulted <see cref="System.Threading.Tasks.Task"/>'s unobserved exception is about to trigger exception escalation
         /// policy, which, by default, would terminate the process.
@@ -466,27 +464,7 @@ namespace System.Threading.Tasks
         /// Each handler is passed a <see cref="T:System.Threading.Tasks.UnobservedTaskExceptionEventArgs"/>
         /// instance, which may be used to examine the exception and to mark it as observed.
         /// </remarks>
-        public static event EventHandler<UnobservedTaskExceptionEventArgs> UnobservedTaskException
-        {
-            add
-            {
-                if (value != null)
-                {
-                    RuntimeHelpers.PrepareContractedDelegate(value);
-                    lock (_unobservedTaskExceptionLockObject) _unobservedTaskException += value;
-                }
-            }
-
-            remove
-            {
-                lock (_unobservedTaskExceptionLockObject) _unobservedTaskException -= value;
-            }
-        }
-
-
-
-
-
+        public static event EventHandler<UnobservedTaskExceptionEventArgs> UnobservedTaskException;
 
         ////////////////////////////////////////////////////////////
         //
@@ -496,17 +474,7 @@ namespace System.Threading.Tasks
         // This is called by the TaskExceptionHolder finalizer.
         internal static void PublishUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs ueea)
         {
-            // Lock this logic to prevent just-unregistered handlers from being called.
-            lock (_unobservedTaskExceptionLockObject)
-            {
-                // Since we are under lock, it is technically no longer necessary
-                // to make a copy.  It is done here for convenience.
-                EventHandler<UnobservedTaskExceptionEventArgs> handler = _unobservedTaskException;
-                if (handler != null)
-                {
-                    handler(sender, ueea);
-                }
-            }
+            UnobservedTaskException?.Invoke(sender, ueea);
         }
 
         /// <summary>
@@ -597,13 +565,13 @@ namespace System.Threading.Tasks
                 m_taskScheduler = scheduler;
             }
 
-            // returns the schedulers Id
+            // returns the scheduler's Id
             public int Id
             {
                 get { return m_taskScheduler.Id; }
             }
 
-            // returns the schedulers GetScheduledTasks
+            // returns the scheduler's GetScheduledTasks
             public IEnumerable<Task> ScheduledTasks
             {
                 get { return m_taskScheduler.GetScheduledTasks(); }
@@ -17,6 +17,8 @@ using System.Diagnostics;
 using System.Collections.Generic;
 using System.Text;
 
+using Internal.Runtime.Augments;
+
 namespace System.Threading.Tasks
 {
     /// <summary>
@@ -45,7 +47,7 @@ namespace System.Threading.Tasks
             if ((options & TaskCreationOptions.LongRunning) != 0)
             {
                 // Run LongRunning tasks on their own dedicated thread.
-                Thread thread = new Thread(s_longRunningThreadWork);
+                RuntimeThread thread = RuntimeThread.Create(s_longRunningThreadWork);
                 thread.IsBackground = true; // Keep this thread from blocking process shutdown
                 thread.Start(task);
             }