Skip to content
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,113 @@ private static void CaptureContinuationContext(ref object continuationContext, r
flags |= ContinuationFlags.ContinueOnThreadPool;
}

// Finish suspension in the common case of a custom await or for a ConfigureAwait(false) task await:
// - Capture current ExecutionContext into the continuation
// - Restore ExecutionContext and SynchronizationContext to the current Thread object
private static void FinishSuspensionNoContinuationContext(ref ExecutionContext? execCtx, bool resumed, ExecutionContext? previousExecCtx, SynchronizationContext? previousSyncCtx)
{
Thread thread = Thread.CurrentThreadAssumedInitialized;

ExecutionContext? threadExecCtx = thread._executionContext;

// Commonly when we reuse a continuation we have already the right
// context saved, or we are saving null and it is already null.
if (threadExecCtx != execCtx)
{
if (threadExecCtx != null && threadExecCtx.InstanceIsFlowSuppressed)
{
execCtx = ExecutionContext.DefaultFlowSuppressed;
}
else
{
execCtx = threadExecCtx;
}
}
else
{
Debug.Assert(threadExecCtx == null || !threadExecCtx.InstanceIsFlowSuppressed);
Comment thread
jakobbotsch marked this conversation as resolved.
}

if (!resumed)
{
if (previousSyncCtx != thread._synchronizationContext)
{
thread._synchronizationContext = previousSyncCtx;
}

if (previousExecCtx != threadExecCtx)
{
thread._executionContext = previousExecCtx;
}
}
}

// Finish suspension in the common case of a standard task await:
// - Record continuation context to determine where to continue on resumption
// - Capture current ExecutionContext into the continuation
// - Restore ExecutionContext and SynchronizationContext to the current Thread object
private static void FinishSuspensionWithContinuationContext(ref object continuationContext, ref ContinuationFlags flags, ref ExecutionContext? execCtx, bool resumed, ExecutionContext? previousExecCtx, SynchronizationContext? previousSyncCtx)
{
Thread thread = Thread.CurrentThreadAssumedInitialized;
SynchronizationContext? threadSyncCtx = thread._synchronizationContext;
if (threadSyncCtx != null && threadSyncCtx.GetType() != typeof(SynchronizationContext))
{
flags |= ContinuationFlags.ContinueOnCapturedSynchronizationContext;
if (continuationContext != threadSyncCtx)
{
continuationContext = threadSyncCtx;
}
}
else
{
TaskScheduler? sched = TaskScheduler.InternalCurrent;
if (sched != null && sched != TaskScheduler.Default)
{
flags |= ContinuationFlags.ContinueOnCapturedTaskScheduler;
if (continuationContext != sched)
{
continuationContext = sched;
}
}
else
{
flags |= ContinuationFlags.ContinueOnThreadPool;
}
}

ExecutionContext? threadExecCtx = thread._executionContext;
// Commonly when we reuse a continuation we have already the right
// context saved, or we are saving null and it is already null.
if (threadExecCtx != execCtx)
{
if (threadExecCtx != null && threadExecCtx.InstanceIsFlowSuppressed)
{
execCtx = ExecutionContext.DefaultFlowSuppressed;
}
else
{
execCtx = threadExecCtx;
}
}
else
{
Debug.Assert(threadExecCtx == null || !threadExecCtx.InstanceIsFlowSuppressed);
Comment thread
jakobbotsch marked this conversation as resolved.
}

if (!resumed)
{
if (previousSyncCtx != threadSyncCtx)
{
thread._synchronizationContext = previousSyncCtx;
}

if (previousExecCtx != threadExecCtx)
{
thread._executionContext = previousExecCtx;
}
}
}

[StackTraceHidden]
internal static T CompletedTaskResult<T>(Task<T> task)
{
Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1844,6 +1844,10 @@ struct CORINFO_ASYNC_INFO
CORINFO_METHOD_HANDLE restoreContextsMethHnd;
// Method handle for AsyncHelpers.RestoreContextsOnSuspension, used before suspending in async methods
CORINFO_METHOD_HANDLE restoreContextsOnSuspensionMethHnd;
// Finish suspension without saving continuation context (i.e. custom awaiter or ConfigureAwait(false))
CORINFO_METHOD_HANDLE finishSuspensionNoContinuationContextMethHnd;
// Finish suspension with saving continuation context (i.e. normal task await)
CORINFO_METHOD_HANDLE finishSuspensionWithContinuationContextMethHnd;
Comment thread
jakobbotsch marked this conversation as resolved.
};

// Flags passed from JIT to runtime.
Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/inc/jiteeversionguid.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@

#include <minipal/guid.h>

constexpr GUID JITEEVersionIdentifier = { /* d4aa533f-231b-4bd3-9d4e-238f88b337cb */
0xd4aa533f,
0x231b,
0x4bd3,
{0x9d, 0x4e, 0x23, 0x8f, 0x88, 0xb3, 0x37, 0xcb}
constexpr GUID JITEEVersionIdentifier = { /* 20635bf4-3384-4080-8cd4-f7caf4798410 */
0x20635bf4,
0x3384,
0x4080,
{0x8c, 0xd4, 0xf7, 0xca, 0xf4, 0x79, 0x84, 0x10}
};

#endif // JIT_EE_VERSIONING_GUID_H
Loading
Loading