Skip to content

Conversation

@wfurt
Copy link
Member

@wfurt wfurt commented Jul 26, 2021

This is recent regression caused by #55468.
When we fail faster than we can return ConnectTcs in ConnectAsync, it may be null and the return would fail.
So instead of setting it to null to prefer double cleanup I added Task.IsCompleted check.

fixes #56263
fixes #56454

@wfurt wfurt requested a review from a team July 26, 2021 04:53
@wfurt wfurt self-assigned this Jul 26, 2021
@ghost
Copy link

ghost commented Jul 26, 2021

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

This is recent regression caused by #55468.
When we fail faster than we can return ConnectTcs in ConnectAsync, it may be null and the return would fail. So instead of setting it to null to prefer double cleanup I added Task.IsCompleted` check.

fixes #56263

Author: wfurt
Assignees: wfurt
Labels:

area-System.Net.Quic

Milestone: -

state.ConnectTcs.SetException(ex);
state.ConnectTcs = null;
// This is opportunistic if we get exception and have ability to propagate it to caller.
state.ConnectTcs.TrySetException(ex);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the change I was hinting at when asking about the race condition.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I can do better fix. Instead of checking state of the task I can simply store TaskCompletionSource in ConnectAsync to local variable and return that. There is really no reason to drag it past Connect event.


uint hresult = connectionEvent.Data.ShutdownInitiatedByTransport.Status;
Exception ex = QuicExceptionHelpers.CreateExceptionForHResult(hresult, "Connection has been shutdown by transport.");
state.ConnectTcs!.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(ex));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't need to be TrySetException as well?

@wfurt
Copy link
Member Author

wfurt commented Jul 27, 2021

I did different fix @stephentoub, can you please take another quic look. To avoid fighting over global state, I store the original tcs in local variable so it would never NRE. And then the state.ConnectTcs is set & cleared on successful connect or on failure. Looks simpler than trying to figure out state of Task.

Copy link
Member

@CarnaViire CarnaViire left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small nit, otherwise LGTM

@wfurt wfurt merged commit 87769fb into dotnet:main Jul 29, 2021
@wfurt wfurt deleted the nre_56263 branch July 29, 2021 05:02
@karelz karelz added this to the 6.0.0 milestone Jul 29, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Aug 28, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Test failure: ConnectWithCertificateForDifferentName_Throws - NullReferenceException Test failure: ConnectWithCertificateCallback

4 participants