Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions src/mscorlib/src/System/IO/Stream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,6 @@ private sealed class ReadWriteTask : Task<int>, ITaskCompletionAction
_buffer = null;
}

[MethodImpl(MethodImplOptions.NoInlining)]
public ReadWriteTask(
bool isRead,
bool apm,
Expand All @@ -630,8 +629,6 @@ public ReadWriteTask(
Contract.Requires(buffer != null);
Contract.EndContractBlock();

StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;

// Store the arguments
_isRead = isRead;
_apm = apm;
Expand All @@ -648,8 +645,7 @@ public ReadWriteTask(
if (callback != null)
{
_callback = callback;
_context = ExecutionContext.Capture(ref stackMark,
ExecutionContext.CaptureOptions.OptimizeDefaultCase | ExecutionContext.CaptureOptions.IgnoreSyncCtx);
_context = ExecutionContext.Capture();
base.AddCompletionAction(this);
}
}
Expand Down Expand Up @@ -683,7 +679,7 @@ void ITaskCompletionAction.Invoke(Task completingTask)
var invokeAsyncCallback = s_invokeAsyncCallback;
if (invokeAsyncCallback == null) s_invokeAsyncCallback = invokeAsyncCallback = InvokeAsyncCallback; // benign race condition

using(context) ExecutionContext.Run(context, invokeAsyncCallback, this, true);
ExecutionContext.Run(context, invokeAsyncCallback, this);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -876,12 +876,12 @@ internal Action GetCompletionAction(Task taskForTracing, ref MoveNextRunner runn
Debugger.NotifyOfCrossThreadDependency();

// The builder needs to flow ExecutionContext, so capture it.
var capturedContext = ExecutionContext.FastCapture(); // ok to use FastCapture as we haven't made any permission demands/asserts
var capturedContext = ExecutionContext.Capture();

// If the ExecutionContext is the default context, try to use a cached delegate, creating one if necessary.
Action action;
MoveNextRunner runner;
if (capturedContext != null && capturedContext.IsPreAllocatedDefault)
if (capturedContext == ExecutionContext.Default)
{
// Get the cached delegate, and if it's non-null, return it.
action = m_defaultContextAction;
Expand Down Expand Up @@ -1016,12 +1016,8 @@ internal void RunWithCapturedContext()

if (m_context != null)
{
try
{
// Use the context and callback to invoke m_stateMachine.MoveNext.
ExecutionContext.Run(m_context, InvokeMoveNextCallback, m_stateMachine, preserveSyncCtx: true);
}
finally { m_context.Dispose(); }
// Use the context and callback to invoke m_stateMachine.MoveNext.
ExecutionContext.Run(m_context, InvokeMoveNextCallback, m_stateMachine);
}
else
{
Expand All @@ -1046,24 +1042,11 @@ internal MoveNextRunner(IAsyncStateMachine stateMachine)
internal void RunWithDefaultContext()
{
Debug.Assert(m_stateMachine != null, "The state machine must have been set before calling Run.");
ExecutionContext.Run(ExecutionContext.PreAllocatedDefault, InvokeMoveNextCallback, m_stateMachine, preserveSyncCtx: true);
ExecutionContext.Run(ExecutionContext.Default, InvokeMoveNextCallback, m_stateMachine);
}

/// <summary>Gets a delegate to the InvokeMoveNext method.</summary>
protected static ContextCallback InvokeMoveNextCallback
{
get { return s_invokeMoveNext ?? (s_invokeMoveNext = InvokeMoveNext); }
}

/// <summary>Cached delegate used with ExecutionContext.Run.</summary>
private static ContextCallback s_invokeMoveNext; // lazily-initialized due to SecurityCritical attribution

/// <summary>Invokes the MoveNext method on the supplied IAsyncStateMachine.</summary>
/// <param name="stateMachine">The IAsyncStateMachine machine instance.</param>
private static void InvokeMoveNext(object stateMachine)
{
((IAsyncStateMachine)stateMachine).MoveNext();
}
protected static readonly ContextCallback InvokeMoveNextCallback = sm => ((IAsyncStateMachine)sm).MoveNext();
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,21 +198,19 @@ private static void ThrowForNonSuccess(Task task)
/// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
/// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
/// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
internal static void OnCompletedInternal(Task task, Action continuation, bool continueOnCapturedContext, bool flowExecutionContext)
{
if (continuation == null) throw new ArgumentNullException(nameof(continuation));
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;

// If TaskWait* ETW events are enabled, trace a beginning event for this await
// and set up an ending event to be traced when the asynchronous await completes.
if ( TplEtwProvider.Log.IsEnabled() || Task.s_asyncDebuggingEnabled)
if (TplEtwProvider.Log.IsEnabled() || Task.s_asyncDebuggingEnabled)
{
continuation = OutputWaitEtwEvents(task, continuation);
}

// Set the continuation onto the awaited task.
task.SetContinuationForAwait(continuation, continueOnCapturedContext, flowExecutionContext, ref stackMark);
task.SetContinuationForAwait(continuation, continueOnCapturedContext, flowExecutionContext);
}

/// <summary>
Expand Down
6 changes: 1 addition & 5 deletions src/mscorlib/src/System/Threading/CancellationToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -317,11 +317,8 @@ internal CancellationTokenRegistration InternalRegisterWithoutEC(Action<object>
}

// the real work..
[MethodImpl(MethodImplOptions.NoInlining)]
private CancellationTokenRegistration Register(Action<Object> callback, Object state, bool useSynchronizationContext, bool useExecutionContext)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;

if (callback == null)
throw new ArgumentNullException(nameof(callback));

Expand All @@ -341,8 +338,7 @@ private CancellationTokenRegistration Register(Action<Object> callback, Object s
if (useSynchronizationContext)
capturedSyncContext = SynchronizationContext.Current;
if (useExecutionContext)
capturedExecutionContext = ExecutionContext.Capture(
ref stackMark, ExecutionContext.CaptureOptions.OptimizeDefaultCase); // ideally we'd also use IgnoreSyncCtx, but that could break compat
capturedExecutionContext = ExecutionContext.Capture();
}

// Register the callback with the source.
Expand Down
48 changes: 5 additions & 43 deletions src/mscorlib/src/System/Threading/ExecutionContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ internal void Undo(Thread currentThread)
[Serializable]
public sealed class ExecutionContext : IDisposable, ISerializable
{
private static readonly ExecutionContext Default = new ExecutionContext();
internal static readonly ExecutionContext Default = new ExecutionContext();

private readonly IAsyncLocalValueMap m_localValues;
private readonly IAsyncLocal[] m_localChangeNotifications;
Expand Down Expand Up @@ -93,16 +93,10 @@ private ExecutionContext(SerializationInfo info, StreamingContext context)
public static ExecutionContext Capture()
{
ExecutionContext executionContext = Thread.CurrentThread.ExecutionContext;
if (executionContext == null)
{
return Default;
}
if (executionContext.m_isFlowSuppressed)
{
// Prevent ExecutionContext.Run on a suppressed-flow context for desktop framework compatibility
return null;
}
return executionContext;
return
executionContext == null ? Default :
executionContext.m_isFlowSuppressed ? null :
executionContext;
}

private ExecutionContext ShallowClone(bool isFlowSuppressed)
Expand Down Expand Up @@ -301,21 +295,6 @@ internal static void SetLocalValue(IAsyncLocal local, object newValue, bool need
}
}

#region Wrappers for CLR compat, to avoid ifdefs all over the BCL

[Flags]
internal enum CaptureOptions
{
None = 0x00,
IgnoreSyncCtx = 0x01,
OptimizeDefaultCase = 0x02,
}

internal static ExecutionContext Capture(ref StackCrawlMark stackMark, CaptureOptions captureOptions)
{
return Capture();
}

[FriendAccessAllowed]
internal static ExecutionContext FastCapture()
{
Expand All @@ -328,11 +307,6 @@ internal static void Run(ExecutionContext executionContext, ContextCallback call
Run(executionContext, callback, state);
}

internal bool IsDefaultFTContext(bool ignoreSyncCtx)
{
return this == Default;
}

public ExecutionContext CreateCopy()
{
return this; // since CoreCLR's ExecutionContext is immutable, we don't need to create copies.
Expand All @@ -342,18 +316,6 @@ public void Dispose()
{
// For CLR compat only
}

internal static ExecutionContext PreAllocatedDefault
{
get { return ExecutionContext.Default; }
}

internal bool IsPreAllocatedDefault
{
get { return this == ExecutionContext.Default; }
}

#endregion
}

public struct AsyncFlowControl : IDisposable
Expand Down
45 changes: 19 additions & 26 deletions src/mscorlib/src/System/Threading/Overlapped.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,11 @@ static _IOCompletionCallback()
{
}

internal _IOCompletionCallback(IOCompletionCallback ioCompletionCallback, ref StackCrawlMark stackMark)
internal _IOCompletionCallback(IOCompletionCallback ioCompletionCallback)
{
_ioCompletionCallback = ioCompletionCallback;
// clone the exection context
_executionContext = ExecutionContext.Capture(
ref stackMark,
ExecutionContext.CaptureOptions.IgnoreSyncCtx | ExecutionContext.CaptureOptions.OptimizeDefaultCase);
_executionContext = ExecutionContext.Capture();
}
// Context callback: same sig for SendOrPostCallback and ContextCallback
static internal ContextCallback _ccb = new ContextCallback(IOCompletionCallback_Context);
Expand All @@ -103,26 +101,23 @@ static unsafe internal void PerformIOCompletionCallback(uint errorCode, // Error
overlapped = OverlappedData.GetOverlappedFromNative(pOVERLAP).m_overlapped;
helper = overlapped.iocbHelper;

if (helper == null || helper._executionContext == null || helper._executionContext.IsDefaultFTContext(true))
{
// We got here because of UnsafePack (or) Pack with EC flow supressed
IOCompletionCallback callback = overlapped.UserCallback;
callback( errorCode, numBytes, pOVERLAP);
}
else
{
// We got here because of Pack
helper._errorCode = errorCode;
helper._numBytes = numBytes;
helper._pOVERLAP = pOVERLAP;
using (ExecutionContext executionContext = helper._executionContext.CreateCopy())
ExecutionContext.Run(executionContext, _ccb, helper, true);
}

//Quickly check the VM again, to see if a packet has arrived.

if (helper == null || helper._executionContext == null || helper._executionContext == ExecutionContext.Default)
{
// We got here because of UnsafePack (or) Pack with EC flow supressed
IOCompletionCallback callback = overlapped.UserCallback;
callback( errorCode, numBytes, pOVERLAP);
}
else
{
// We got here because of Pack
helper._errorCode = errorCode;
helper._numBytes = numBytes;
helper._pOVERLAP = pOVERLAP;
ExecutionContext.Run(helper._executionContext, _ccb, helper);
}

//Quickly check the VM again, to see if a packet has arrived.
OverlappedData.CheckVMForIOPacket(out pOVERLAP, out errorCode, out numBytes);

} while (pOVERLAP != null);

}
Expand Down Expand Up @@ -174,17 +169,15 @@ internal void ReInitialize()
m_nativeOverlapped.InternalHigh = (IntPtr)0;
}

[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
unsafe internal NativeOverlapped* Pack(IOCompletionCallback iocb, Object userData)
{
if (!m_pinSelf.IsNull()) {
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_Overlapped_Pack"));
}
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;

if (iocb != null)
{
m_iocbHelper = new _IOCompletionCallback(iocb, ref stackMark);
m_iocbHelper = new _IOCompletionCallback(iocb);
m_iocb = iocb;
}
else
Expand Down
Loading