diff options
author | Stephen Toub <stoub@microsoft.com> | 2018-03-08 22:26:14 +0300 |
---|---|---|
committer | Stephen Toub <stoub@microsoft.com> | 2018-03-09 02:43:47 +0300 |
commit | 2a160877d0a57df458fd51948164062cdfb8fae8 (patch) | |
tree | 788456205e08f4a8afc6c0f904205155a36cde2f /external | |
parent | da8f962c3b9c86883d0aefe72109fdb6319fd385 (diff) |
Fix inlining of IAsyncStateMachineBox (dotnet/coreclr#16830)
Prior to .NET Core 2.1, if a task was awaited in a default context (or if ConfigureAwait(false) was used), and if the task was then completed on a non-default context (e.g. code running a non-default TaskScheduler calling SetResult on a TaskCompletionSource), its await continuations are not allowed to be inlined, due to concerns that we could be running an arbitrary amount of unknown code in a scheduling environment that's not amenable to it, like a UI thread. The optimizations added in 2.1 erroneously ended up bypassing that IsValidLocationForInlining check, leading to continuations getting inlined in places they weren't previously.
This commit fixes that. Previously we'd made the IAsyncStateMachineBox interface inherit ITaskCompletionAction, with its Invoke interface method just delegating to MoveNext; then the box could be added to a task as a continuation. But that ITaskCompletionAction logic isn't specific to async/await and doesn't invoke IsValidLocationForInlining. We instead need to follow the Action logic that is meant to be used for async/await. I've removed the ITaskCompletionAction from IAsyncStateMachineBox, replacing it just with a MoveNext interface method, and added a case for IAsyncStateMachineBox to Task's RunContinuations logic. I then duplicated the AwaitTaskContinuation.RunOrScheduleAction logic that's there for Action and tweaked it for IAsyncStateMachineBox. In the process I cleaned up a little code to use some newer C# features.
Signed-off-by: dotnet-bot-corefx-mirror <dotnet-bot@microsoft.com>
Diffstat (limited to 'external')
0 files changed, 0 insertions, 0 deletions