summaryrefslogtreecommitdiff
path: root/src/mscorlib
diff options
context:
space:
mode:
authorStephen Toub <stoub@microsoft.com>2016-02-11 18:15:17 -0500
committerStephen Toub <stoub@microsoft.com>2016-02-11 18:15:17 -0500
commitffa6fdff2d5acc7cd385a55f185a25c5e8fa8ad7 (patch)
tree888c4ab1942db613e9ab61f4b5934c18e1da8afc /src/mscorlib
parent6ac7e9639630c60a7e102b0f8465179262e26550 (diff)
parentae413bc05a6021c5164cc34d899084bc2a2a0579 (diff)
downloadcoreclr-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.cs43
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs1
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.