Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce execution time of Socket handle inheritance tests #31813

Merged

Conversation

antonfirsov
Copy link
Member

Follow up for the discussion under #1858 (comment)

This PR reduces the execution time for CtorAndAccept_SocketNotKeptAliveViaInheritance and DuplicateSocket_IsNotInheritable from 2sec+ to ~800ms on Windows.

The tests were running long because of the long time WSAConnect keeps blocking the caller before failing.

@antonfirsov antonfirsov requested review from a team and stephentoub February 5, 2020 18:48
@davidsh davidsh added area-System.Net.Sockets test-enhancement Improvements of test source code labels Feb 5, 2020
@davidsh davidsh added this to the 5.0 milestone Feb 5, 2020
// Useful to speed up "can not connect" assertions on Windows
public static bool TryConnect(this Socket socket, EndPoint remoteEndpoint, int millisecondsTimeout)
{
using var mre = new ManualResetEvent(false);
Copy link
Member

Choose a reason for hiding this comment

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

Nit: doesn't matter as much for tests, but it'd be cheaper to use ManualResetEventSlim

Copy link
Member

Choose a reason for hiding this comment

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

Probably better not to dispose of this. You currently have a race condition where you could dispose of it and then set it.

Copy link
Member Author

@antonfirsov antonfirsov Feb 6, 2020

Choose a reason for hiding this comment

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

Re MRE:
Initially I wanted to use the slim variant, but I was afraid that the spinning could make things worse. Isn't 300ms too long for ManualResetEventSlim? Any resources / guidance about how to choose?

Re Dispose:
See my next comment.

Copy link
Member

Choose a reason for hiding this comment

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

I was afraid that the spinning could make things worse. Isn't 300ms too long for ManualResetEventSlim?

MRES doesn't just spin; after a tiny amount of spinning it'll fall back to an actual kernel wait.

If you're actually concerned about it (and I don't think you need to be), you can pass spinCount: 0 to the ctor.

return sea.SocketError == SocketError.Success;
}

sea.UserToken = null; // Letting the event handler know that we timed out
Copy link
Member

Choose a reason for hiding this comment

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

Not really necessary; you could have the event handler always set it and not null it out. Then you can remove this like and simplify the handler to just:

sea.Completed += (s, e) => ((ManualResetEventSlim)e.UserToken).Set();

Copy link
Member Author

@antonfirsov antonfirsov Feb 6, 2020

Choose a reason for hiding this comment

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

I'm doing this to address the race condition you pointed out in your previous comment. Without this, a pending operation may try to use a disposed MRE.

With the current logic, we are safe unless an unexpected exception is thrown.

Copy link
Member Author

@antonfirsov antonfirsov Feb 6, 2020

Choose a reason for hiding this comment

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

Ok you are right, I still have a race around the if in the handler, but it seems unlikely to cause trouble in test code.

Is it indeed safer to just leave the MRE undisposed instead?

Copy link
Member

Choose a reason for hiding this comment

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

it seems unlikely to cause trouble in test code.

I can almost guarantee it would happen at some point in CI and cause a spurious test failure.

Is it indeed safer to just leave the MRE undisposed instead?

Yes

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, fixed.

Copy link
Member

@wfurt wfurt left a comment

Choose a reason for hiding this comment

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

LGTM.

@antonfirsov
Copy link
Member Author

@stephentoub @wfurt anything against merging this as it is now?

@antonfirsov
Copy link
Member Author

/azp run runtime-libraries outerloop

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@antonfirsov
Copy link
Member Author

No tests failures seem to be related with the changes in this PR.
We can add additional improvements like configurable timeout later.

@antonfirsov antonfirsov merged commit 7871fc1 into dotnet:master Feb 17, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Net.Sockets test-enhancement Improvements of test source code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants