@@ -134,8 +134,6 @@ public class Task : IThreadPoolWorkItem, IAsyncResult, IDisposable
134
134
{
135
135
[ ThreadStatic ]
136
136
internal static Task t_currentTask ; // The currently executing task.
137
- [ ThreadStatic ]
138
- private static StackGuard t_stackGuard ; // The stack guard object for this thread
139
137
140
138
internal static int s_taskIdCounter ; //static counter used to generate unique task IDs
141
139
@@ -1276,23 +1274,6 @@ internal static Task InternalCurrentIfAttached(TaskCreationOptions creationOptio
1276
1274
return ( creationOptions & TaskCreationOptions . AttachedToParent ) != 0 ? InternalCurrent : null ;
1277
1275
}
1278
1276
1279
- /// <summary>
1280
- /// Gets the StackGuard object assigned to the current thread.
1281
- /// </summary>
1282
- internal static StackGuard CurrentStackGuard
1283
- {
1284
- get
1285
- {
1286
- StackGuard sg = t_stackGuard ;
1287
- if ( sg == null )
1288
- {
1289
- t_stackGuard = sg = new StackGuard ( ) ;
1290
- }
1291
- return sg ;
1292
- }
1293
- }
1294
-
1295
-
1296
1277
/// <summary>
1297
1278
/// Gets the <see cref="T:System.AggregateException">Exception</see> that caused the <see
1298
1279
/// cref="Task">Task</see> to end prematurely. If the <see
@@ -3263,7 +3244,8 @@ private void RunContinuations(object continuationObject) // separated out of Fin
3263
3244
// Skip synchronous execution of continuations if this task's thread was aborted
3264
3245
bool canInlineContinuations = ! ( ( ( m_stateFlags & TASK_STATE_THREAD_WAS_ABORTED ) != 0 ) ||
3265
3246
( RuntimeThread . CurrentThread . ThreadState == ThreadState . AbortRequested ) ||
3266
- ( ( m_stateFlags & ( int ) TaskCreationOptions . RunContinuationsAsynchronously ) != 0 ) ) ;
3247
+ ( ( m_stateFlags & ( int ) TaskCreationOptions . RunContinuationsAsynchronously ) != 0 ) )
3248
+ && RuntimeHelpers . TryEnsureSufficientExecutionStack ( ) ;
3267
3249
3268
3250
switch ( continuationObject )
3269
3251
{
@@ -6415,56 +6397,6 @@ public enum TaskContinuationOptions
6415
6397
ExecuteSynchronously = 0x80000
6416
6398
}
6417
6399
6418
- /// <summary>
6419
- /// Internal helper class to keep track of stack depth and decide whether we should inline or not.
6420
- /// </summary>
6421
- internal class StackGuard
6422
- {
6423
- // current thread's depth of nested inline task executions
6424
- private int m_inliningDepth = 0 ;
6425
-
6426
- // For relatively small inlining depths we don't want to get into the business of stack probing etc.
6427
- // This clearly leaves a window of opportunity for the user code to SO. However a piece of code
6428
- // that can SO in 20 inlines on a typical 1MB stack size probably needs to be revisited anyway.
6429
- private const int MAX_UNCHECKED_INLINING_DEPTH = 20 ;
6430
-
6431
- /// <summary>
6432
- /// This method needs to be called before attempting inline execution on the current thread.
6433
- /// If false is returned, it means we are too close to the end of the stack and should give up inlining.
6434
- /// Each call to TryBeginInliningScope() that returns true must be matched with a
6435
- /// call to EndInliningScope() regardless of whether inlining actually took place.
6436
- /// </summary>
6437
- internal bool TryBeginInliningScope ( )
6438
- {
6439
- // If we're still under the 'safe' limit we'll just skip the stack probe to save p/invoke calls
6440
- if ( m_inliningDepth < MAX_UNCHECKED_INLINING_DEPTH || CheckForSufficientStack ( ) )
6441
- {
6442
- m_inliningDepth ++ ;
6443
- return true ;
6444
- }
6445
- else
6446
- return false ;
6447
- }
6448
-
6449
- /// <summary>
6450
- /// This needs to be called once for each previous successful TryBeginInliningScope() call after
6451
- /// inlining related logic runs.
6452
- /// </summary>
6453
- internal void EndInliningScope ( )
6454
- {
6455
- m_inliningDepth -- ;
6456
- Debug . Assert ( m_inliningDepth >= 0 , "Inlining depth count should never go negative." ) ;
6457
-
6458
- // do the right thing just in case...
6459
- if ( m_inliningDepth < 0 ) m_inliningDepth = 0 ;
6460
- }
6461
-
6462
- private unsafe bool CheckForSufficientStack ( )
6463
- {
6464
- return RuntimeHelpers . TryEnsureSufficientExecutionStack ( ) ;
6465
- }
6466
- }
6467
-
6468
6400
// Special internal struct that we use to signify that we are not interested in
6469
6401
// a Task<VoidTaskResult>'s result.
6470
6402
internal struct VoidTaskResult { }
@@ -6546,18 +6478,17 @@ public UnwrapPromise(Task outerTask, bool lookForOce)
6546
6478
// For ITaskCompletionAction
6547
6479
public void Invoke ( Task completingTask )
6548
6480
{
6549
- // Check the current stack guard. If we're ok to inline,
6550
- // process the task, and reset the guard when we're done.
6551
- var sg = Task . CurrentStackGuard ;
6552
- if ( sg . TryBeginInliningScope ( ) )
6481
+ // If we're ok to inline, process the task. Otherwise, we're too deep on the stack, and
6482
+ // we shouldn't run the continuation chain here, so queue a work item to call back here
6483
+ // to Invoke asynchronously.
6484
+ if ( RuntimeHelpers . TryEnsureSufficientExecutionStack ( ) )
6485
+ {
6486
+ InvokeCore ( completingTask ) ;
6487
+ }
6488
+ else
6553
6489
{
6554
- try { InvokeCore ( completingTask ) ; }
6555
- finally { sg . EndInliningScope ( ) ; }
6490
+ InvokeCoreAsync ( completingTask ) ;
6556
6491
}
6557
- // Otherwise, we're too deep on the stack, and
6558
- // we shouldn't run the continuation chain here, so queue a work
6559
- // item to call back here to Invoke asynchronously.
6560
- else InvokeCoreAsync ( completingTask ) ;
6561
6492
}
6562
6493
6563
6494
/// <summary>
0 commit comments