summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStephen Toub <stoub@microsoft.com>2018-06-28 10:26:21 -0400
committerGitHub <noreply@github.com>2018-06-28 10:26:21 -0400
commit7d72463b1107cc6f264fcbdc06e3c4df0d9ed668 (patch)
tree466cdf3d0f3e51d7d08d8dfcabdd0cc0db385b1d /src
parent83bdd210b40dac4d42ca8775bfe63d935ab9af2c (diff)
downloadcoreclr-7d72463b1107cc6f264fcbdc06e3c4df0d9ed668.tar.gz
coreclr-7d72463b1107cc6f264fcbdc06e3c4df0d9ed668.tar.bz2
coreclr-7d72463b1107cc6f264fcbdc06e3c4df0d9ed668.zip
Avoid capturing ExecutionContext into CancellationTokenSource's Timer (#18670)
* Avoid capturing ExecutionContext into CancellationTokenSource's Timer It's not needed, and it can keep unrelated state alive unnecessarily * Address PR feedback
Diffstat (limited to 'src')
-rw-r--r--src/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs4
-rw-r--r--src/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs2
-rw-r--r--src/System.Private.CoreLib/src/System/Threading/Timer.cs25
3 files changed, 22 insertions, 9 deletions
diff --git a/src/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs b/src/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs
index 7f41d250b6..d38ffc966e 100644
--- a/src/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs
+++ b/src/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs
@@ -205,7 +205,7 @@ namespace System.Threading
private void InitializeWithTimer(int millisecondsDelay)
{
_state = NotCanceledState;
- _timer = new Timer(s_timerCallback, this, millisecondsDelay, -1);
+ _timer = new Timer(s_timerCallback, this, millisecondsDelay, -1, flowExecutionContext: false);
}
/// <summary>Communicates a request for cancellation.</summary>
@@ -345,7 +345,7 @@ namespace System.Threading
// Initially set to "never go off" because we don't want to take a
// chance on a timer "losing" the initialization and then
// cancelling the token before it (the timer) can be disposed.
- Timer newTimer = new Timer(s_timerCallback, this, -1, -1);
+ Timer newTimer = new Timer(s_timerCallback, this, -1, -1, flowExecutionContext: false);
if (Interlocked.CompareExchange(ref _timer, newTimer, null) != null)
{
// We did not initialize the timer. Dispose the new timer.
diff --git a/src/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs b/src/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs
index eb0227014f..a8926bbf7b 100644
--- a/src/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs
+++ b/src/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs
@@ -5419,7 +5419,7 @@ namespace System.Threading.Tasks
// ... and create our timer and make sure that it stays rooted.
if (millisecondsDelay != Timeout.Infinite) // no need to create the timer if it's an infinite timeout
{
- promise.Timer = new TimerQueueTimer(state => ((DelayPromise)state).Complete(), promise, (uint)millisecondsDelay, Timeout.UnsignedInfinite);
+ promise.Timer = new TimerQueueTimer(state => ((DelayPromise)state).Complete(), promise, (uint)millisecondsDelay, Timeout.UnsignedInfinite, flowExecutionContext: false);
}
// Return the timer proxy task
diff --git a/src/System.Private.CoreLib/src/System/Threading/Timer.cs b/src/System.Private.CoreLib/src/System/Threading/Timer.cs
index 4d5c1c7fc1..d9aa01e505 100644
--- a/src/System.Private.CoreLib/src/System/Threading/Timer.cs
+++ b/src/System.Private.CoreLib/src/System/Threading/Timer.cs
@@ -440,13 +440,16 @@ namespace System.Threading
private volatile WaitHandle m_notifyWhenNoCallbacksRunning;
- internal TimerQueueTimer(TimerCallback timerCallback, object state, uint dueTime, uint period)
+ internal TimerQueueTimer(TimerCallback timerCallback, object state, uint dueTime, uint period, bool flowExecutionContext)
{
m_timerCallback = timerCallback;
m_state = state;
m_dueTime = Timeout.UnsignedInfinite;
m_period = Timeout.UnsignedInfinite;
- m_executionContext = ExecutionContext.Capture();
+ if (flowExecutionContext)
+ {
+ m_executionContext = ExecutionContext.Capture();
+ }
m_associatedTimerQueue = TimerQueue.Instances[RuntimeThread.GetCurrentProcessorId() % TimerQueue.Instances.Length];
//
@@ -677,14 +680,23 @@ namespace System.Threading
public Timer(TimerCallback callback,
object state,
int dueTime,
- int period)
+ int period) :
+ this(callback, state, dueTime, period, flowExecutionContext: true)
+ {
+ }
+
+ internal Timer(TimerCallback callback,
+ object state,
+ int dueTime,
+ int period,
+ bool flowExecutionContext)
{
if (dueTime < -1)
throw new ArgumentOutOfRangeException(nameof(dueTime), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
if (period < -1)
throw new ArgumentOutOfRangeException(nameof(period), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
- TimerSetup(callback, state, (uint)dueTime, (uint)period);
+ TimerSetup(callback, state, (uint)dueTime, (uint)period, flowExecutionContext);
}
public Timer(TimerCallback callback,
@@ -745,12 +757,13 @@ namespace System.Threading
private void TimerSetup(TimerCallback callback,
object state,
uint dueTime,
- uint period)
+ uint period,
+ bool flowExecutionContext = true)
{
if (callback == null)
throw new ArgumentNullException(nameof(TimerCallback));
- m_timer = new TimerHolder(new TimerQueueTimer(callback, state, dueTime, period));
+ m_timer = new TimerHolder(new TimerQueueTimer(callback, state, dueTime, period, flowExecutionContext));
}
public bool Change(int dueTime, int period)