diff options
Diffstat (limited to 'mcs/class/referencesource/mscorlib/system/threading/Tasks')
3 files changed, 32 insertions, 22 deletions
diff --git a/mcs/class/referencesource/mscorlib/system/threading/Tasks/FutureFactory.cs b/mcs/class/referencesource/mscorlib/system/threading/Tasks/FutureFactory.cs index f1ed794ccce..f17b2462e40 100644 --- a/mcs/class/referencesource/mscorlib/system/threading/Tasks/FutureFactory.cs +++ b/mcs/class/referencesource/mscorlib/system/threading/Tasks/FutureFactory.cs @@ -851,14 +851,15 @@ namespace System.Threading.Tasks // change will likely brake 4.5 behavior so if possible never touch this code again. if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5) { + var invoked = new AtomicBoolean (); //This is 4.5 behaviour //if we don't require synchronization, a faster set result path is taken var asyncResult = beginMethod(iar => { - if (!iar.CompletedSynchronously) + if (invoked.TryRelaxedSet ()) FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true); }, state); - if (asyncResult.CompletedSynchronously) + if (asyncResult != null && asyncResult.CompletedSynchronously && invoked.TryRelaxedSet ()) { Contract.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed."); FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: false); @@ -991,13 +992,14 @@ namespace System.Threading.Tasks // change will likely brake 4.5 behavior so if possible never touch this code again. if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5) { + var invoked = new AtomicBoolean (); //if we don't require synchronization, a faster set result path is taken var asyncResult = beginMethod(arg1, iar => { - if (!iar.CompletedSynchronously) + if (invoked.TryRelaxedSet ()) FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true); }, state); - if (asyncResult.CompletedSynchronously) + if (asyncResult != null && asyncResult.CompletedSynchronously && invoked.TryRelaxedSet ()) { Contract.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed."); FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: false); @@ -1138,13 +1140,14 @@ namespace System.Threading.Tasks // change will likely brake 4.5 behavior so if possible never touch this code again. if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5) { + var invoked = new AtomicBoolean (); //if we don't require synchronization, a faster set result path is taken var asyncResult = beginMethod(arg1, arg2, iar => { - if (!iar.CompletedSynchronously) + if (invoked.TryRelaxedSet ()) FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true); }, state); - if (asyncResult.CompletedSynchronously) + if (asyncResult != null && asyncResult.CompletedSynchronously && invoked.TryRelaxedSet ()) { Contract.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed."); FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: false); @@ -1293,13 +1296,14 @@ namespace System.Threading.Tasks // change will likely brake 4.5 behavior so if possible never touch this code again. if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5) { + var invoked = new AtomicBoolean (); //if we don't require synchronization, a faster set result path is taken var asyncResult = beginMethod(arg1, arg2, arg3, iar => { - if (!iar.CompletedSynchronously) + if (invoked.TryRelaxedSet ()) FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true); }, state); - if (asyncResult.CompletedSynchronously) + if (asyncResult != null && asyncResult.CompletedSynchronously && invoked.TryRelaxedSet ()) { Contract.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed."); FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: false); @@ -1365,7 +1369,7 @@ namespace System.Threading.Tasks // If the IAsyncResult completed asynchronously, completing the promise will be handled by the callback. // If it completed synchronously, we'll handle that here. - if (asyncResult.CompletedSynchronously) + if (asyncResult != null && asyncResult.CompletedSynchronously) { Contract.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed."); promise.Complete(thisRef, endMethod, asyncResult, requiresSynchronization: false); diff --git a/mcs/class/referencesource/mscorlib/system/threading/Tasks/Task.cs b/mcs/class/referencesource/mscorlib/system/threading/Tasks/Task.cs index 888027770ee..75e440fcf3b 100644 --- a/mcs/class/referencesource/mscorlib/system/threading/Tasks/Task.cs +++ b/mcs/class/referencesource/mscorlib/system/threading/Tasks/Task.cs @@ -594,10 +594,10 @@ namespace System.Threading.Tasks ~(TaskCreationOptions.AttachedToParent | TaskCreationOptions.LongRunning | #if !FEATURE_CORECLR || FEATURE_NETCORE - TaskCreationOptions.DenyChildAttach | + TaskCreationOptions.DenyChildAttach | TaskCreationOptions.HideScheduler | #endif - TaskCreationOptions.PreferFairness)) != 0) + TaskCreationOptions.PreferFairness)) != 0) { throw new ArgumentOutOfRangeException("creationOptions"); } @@ -644,9 +644,9 @@ namespace System.Threading.Tasks if (m_parent != null && ((creationOptions & TaskCreationOptions.AttachedToParent) != 0) #if !FEATURE_CORECLR || FEATURE_NETCORE - && ((m_parent.CreationOptions & TaskCreationOptions.DenyChildAttach) == 0) + && ((m_parent.CreationOptions & TaskCreationOptions.DenyChildAttach) == 0) #endif -) + ) { m_parent.AddNewChild(); } @@ -681,13 +681,13 @@ namespace System.Threading.Tasks // If an unstarted task has a valid CancellationToken that gets signalled while the task is still not queued // we need to proactively cancel it, because it may never execute to transition itself. // The only way to accomplish this is to register a callback on the CT. - // We exclude Promise tasks from this, because TaskCompletionSource needs to fully control the inner tasks's lifetime (i.e. not allow external cancellations) + // We exclude Promise tasks from this, because TaskCompletionSource needs to fully control the inner tasks's lifetime (i.e. not allow external cancellations) if ((((InternalTaskOptions)Options & (InternalTaskOptions.QueuedByRuntime | InternalTaskOptions.PromiseTask #if !FEATURE_CORECLR || FEATURE_NETCORE - | InternalTaskOptions.LazyCancellation + | InternalTaskOptions.LazyCancellation #endif -)) == 0)) + )) == 0)) { if (cancellationToken.IsCancellationRequested) { @@ -720,12 +720,12 @@ namespace System.Threading.Tasks { // If we have an exception related to our CancellationToken, then we need to subtract ourselves // from our parent before throwing it. - if ((m_parent != null) && - ((Options & TaskCreationOptions.AttachedToParent) != 0) + if ((m_parent != null) + && ((Options & TaskCreationOptions.AttachedToParent) != 0) #if !FEATURE_CORECLR || FEATURE_NETCORE - && ((m_parent.Options & TaskCreationOptions.DenyChildAttach) == 0) + && ((m_parent.Options & TaskCreationOptions.DenyChildAttach) == 0) #endif -) + ) { m_parent.DisregardChild(); } @@ -6682,8 +6682,6 @@ namespace System.Threading.Tasks #endif return tasks; } - - } // Proxy class for better debugging experience diff --git a/mcs/class/referencesource/mscorlib/system/threading/Tasks/TaskScheduler.cs b/mcs/class/referencesource/mscorlib/system/threading/Tasks/TaskScheduler.cs index 81226e07e9f..7ca0c6f3dd2 100644 --- a/mcs/class/referencesource/mscorlib/system/threading/Tasks/TaskScheduler.cs +++ b/mcs/class/referencesource/mscorlib/system/threading/Tasks/TaskScheduler.cs @@ -341,6 +341,14 @@ namespace System.Threading.Tasks } } + internal static bool IsDefault + { + get + { + return Current == Default; + } + } + /// <summary> /// Gets the <see cref="System.Threading.Tasks.TaskScheduler">TaskScheduler</see> /// associated with the currently executing task. |