Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs12
-rw-r--r--mcs/class/referencesource/mscorlib/system/threading/Tasks/FutureFactory.cs22
-rw-r--r--mcs/class/referencesource/mscorlib/system/threading/Tasks/Task.cs24
-rw-r--r--mcs/class/referencesource/mscorlib/system/threading/Tasks/TaskScheduler.cs8
4 files changed, 44 insertions, 22 deletions
diff --git a/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs b/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs
index fa6b3d92ca8..5c6833f33e7 100644
--- a/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs
+++ b/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs
@@ -825,16 +825,28 @@ namespace System.Runtime.CompilerServices
// so that they won't "leak" out of the first await.
Thread currentThread = Thread.CurrentThread;
+#if MONO
+ ExecutionContext.Switcher ecs = default (ExecutionContext.Switcher);
+#else
ExecutionContextSwitcher ecs = default(ExecutionContextSwitcher);
+#endif
RuntimeHelpers.PrepareConstrainedRegions();
try
{
+#if MONO
+ currentThread.BranchExecutionContext (out ecs);
+#else
ExecutionContext.EstablishCopyOnWriteScope(currentThread, false, ref ecs);
+#endif
stateMachine.MoveNext();
}
finally
{
+#if MONO
+ currentThread.RestoreExecutionContext (ref ecs);
+#else
ecs.Undo(currentThread);
+#endif
}
}
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.