diff options
author | Stephen Toub <stoub@microsoft.com> | 2016-02-11 18:15:17 -0500 |
---|---|---|
committer | Stephen Toub <stoub@microsoft.com> | 2016-02-11 18:15:17 -0500 |
commit | ffa6fdff2d5acc7cd385a55f185a25c5e8fa8ad7 (patch) | |
tree | 888c4ab1942db613e9ab61f4b5934c18e1da8afc /src/mscorlib | |
parent | 6ac7e9639630c60a7e102b0f8465179262e26550 (diff) | |
parent | ae413bc05a6021c5164cc34d899084bc2a2a0579 (diff) | |
download | coreclr-ffa6fdff2d5acc7cd385a55f185a25c5e8fa8ad7.tar.gz coreclr-ffa6fdff2d5acc7cd385a55f185a25c5e8fa8ad7.tar.bz2 coreclr-ffa6fdff2d5acc7cd385a55f185a25c5e8fa8ad7.zip |
Merge pull request #3132 from stephentoub/taskscheduler_tracking
Track TaskSchedulers only when debugger attached
Diffstat (limited to 'src/mscorlib')
-rw-r--r-- | src/mscorlib/src/System/Threading/Tasks/TaskScheduler.cs | 43 | ||||
-rw-r--r-- | src/mscorlib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs | 1 |
2 files changed, 36 insertions, 8 deletions
diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskScheduler.cs b/src/mscorlib/src/System/Threading/Tasks/TaskScheduler.cs index 1cb5c458b3..f82492499c 100644 --- a/src/mscorlib/src/System/Threading/Tasks/TaskScheduler.cs +++ b/src/mscorlib/src/System/Threading/Tasks/TaskScheduler.cs @@ -278,8 +278,8 @@ namespace System.Threading.Tasks // Member variables // - // The global container that keeps track of TaskScheduler instances. s_activeTaskSchedulers must be initialized before s_defaultTaskScheduler. - private static readonly ConditionalWeakTable<TaskScheduler, object> s_activeTaskSchedulers = new ConditionalWeakTable<TaskScheduler,object>(); + // The global container that keeps track of TaskScheduler instances for debugging purposes. + private static ConditionalWeakTable<TaskScheduler, object> s_activeTaskSchedulers; // An AppDomain-wide default manager. private static readonly TaskScheduler s_defaultTaskScheduler = new ThreadPoolTaskScheduler(); @@ -296,16 +296,32 @@ namespace System.Threading.Tasks // // Constructors and public properties // - + /// <summary> /// Initializes the <see cref="System.Threading.Tasks.TaskScheduler"/>. /// </summary> protected TaskScheduler() { - // Protected constructor. It's here to ensure all user implemented TaskSchedulers will be - // registered in the active schedulers list. - Contract.Assert(s_activeTaskSchedulers != null, "Expected non-null s_activeTaskSchedulers"); - s_activeTaskSchedulers.Add(this, null); + // 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 + // schedulers created while the debugger is attached. + if (Debugger.IsAttached) + { + AddToActiveTaskSchedulers(); + } + } + + /// <summary>Adds this scheduler ot the active schedulers tracking collection for debugging purposes.</summary> + private void AddToActiveTaskSchedulers() + { + ConditionalWeakTable<TaskScheduler, object> activeTaskSchedulers = s_activeTaskSchedulers; + if (activeTaskSchedulers == null) + { + Interlocked.CompareExchange(ref s_activeTaskSchedulers, new ConditionalWeakTable<TaskScheduler, object>(), null); + activeTaskSchedulers = s_activeTaskSchedulers; + } + activeTaskSchedulers.Add(this, null); } /// <summary> @@ -553,9 +569,20 @@ namespace System.Threading.Tasks [SecurityCritical] internal static TaskScheduler[] GetTaskSchedulersForDebugger() { - Contract.Assert(s_activeTaskSchedulers != null, "Expected non-null s_activeTaskSchedulers"); + if (s_activeTaskSchedulers == null) + { + // No schedulers were tracked. Just give back the default. + return new TaskScheduler[] { s_defaultTaskScheduler }; + } ICollection<TaskScheduler> schedulers = s_activeTaskSchedulers.Keys; + if (!schedulers.Contains(s_defaultTaskScheduler)) + { + // Make sure the default is included, in case the debugger attached + // after it was created. + schedulers.Add(s_defaultTaskScheduler); + } + var arr = new TaskScheduler[schedulers.Count]; schedulers.CopyTo(arr, 0); foreach (var scheduler in arr) diff --git a/src/mscorlib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs b/src/mscorlib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs index e0abcb9672..dd4cbc9a66 100644 --- a/src/mscorlib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs +++ b/src/mscorlib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs @@ -29,6 +29,7 @@ namespace System.Threading.Tasks /// </summary> internal ThreadPoolTaskScheduler() { + int id = base.Id; // force ID creation of the default scheduler } // static delegate for threads allocated to handle LongRunning tasks. |