Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Socket.Select: increase ref count while the handle is in use - #41763

Merged
stephentoub merged 4 commits into
dotnet:masterfrom
tmds:select_safehandle
Oct 23, 2019
Merged

Socket.Select: increase ref count while the handle is in use#41763
stephentoub merged 4 commits into
dotnet:masterfrom
tmds:select_safehandle

Conversation

@tmds

@tmds tmds commented Oct 14, 2019

Copy link
Copy Markdown
Member

@davidsh davidsh added this to the 5.0 milestone Oct 14, 2019
@davidsh
davidsh requested a review from a team October 14, 2019 16:50
@wfurt

wfurt commented Oct 14, 2019

Copy link
Copy Markdown
Member

why do we need this @tmds? Should SafeHandle be sufficient to keep it alive?

Comment thread src/System.Net.Sockets/src/System/Net/Sockets/Socket.Windows.cs Outdated
Comment thread src/System.Net.Sockets/src/System/Net/Sockets/Socket.cs
Comment thread src/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs Outdated

fileDescriptorSet[current + 1] = ((Socket)socketList[current])._handle.DangerousGetHandle();
bool success = false;
socket.SafeHandle.DangerousAddRef(ref success);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

With your other PR, accessing socket.SafeHandle is now going to mark the handle as exposed. Is that necessary? Should we instead be using _handle here and everywhere else internally where the handle is used?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I've just added an InternalSafeHandle property to the other PR. Once it is merged, I'll rebase and use it here.

@stephentoub

Copy link
Copy Markdown
Member

why do we need this @tmds? Should SafeHandle be sufficient to keep it alive?

The problem is the implementation isn't just passing SafeHandle to P/Invokes, where the marshaling layer would implicitly addref and release around the native call. Rather, the implementation is calling DangerousGetHandle, returning the raw pointer to then be used. Any usage of that raw handle is no longer guarded by the SafeHandle; instead, the SafeHandle needs to have its ref count increased prior to any usage of the raw handle and its ref count then decremented after. Otherwise, Dispose'ing of the SafeHandle could cause the handle to be closed and even recycled while it's still in use.

@wfurt

wfurt commented Oct 14, 2019

Copy link
Copy Markdown
Member

why do we need this @tmds? Should SafeHandle be sufficient to keep it alive?

The problem is the implementation isn't just passing SafeHandle to P/Invokes, where the marshaling layer would implicitly addref and release around the native call. Rather, the implementation is calling DangerousGetHandle, returning the raw pointer to then be used. Any usage of that raw handle is no longer guarded by the SafeHandle; instead, the SafeHandle needs to have its ref count increased prior to any usage of the raw handle and its ref count then decremented after. Otherwise, Dispose'ing of the SafeHandle could cause the handle to be closed and even recycled while it's still in use.

I was under impression that was fixed in 3.0. If not, shoud we pass SafeHandle to the call?
I did not see any linked issues so I'm trying understand where this come form.

@stephentoub

Copy link
Copy Markdown
Member

shoud we pass SafeHandle to the call?

We need to be able to pass a variable number of handles / file descriptors in an array; we can't do that with SafeHandle.

I was under impression that was fixed in 3.0.

What specifically?

@tmds

tmds commented Oct 15, 2019

Copy link
Copy Markdown
Member Author

I was under impression that was fixed in 3.0.

For the operations that take a single handle, the raw values were replaced by SafeHandle marshalling as part of #38804. Socket.Select wasn't changed yet.

@tmds
tmds force-pushed the select_safehandle branch from 72c6bbd to f993aab Compare October 16, 2019 14:01
@tmds
tmds force-pushed the select_safehandle branch from f993aab to 328d455 Compare October 16, 2019 14:05
@stephentoub

stephentoub commented Oct 21, 2019

Copy link
Copy Markdown
Member

The failures here (at least some of them) appear to be related hangs:

[Long Running Test] 'System.Net.Sockets.Tests.AcceptSync.AcceptGetsCanceledByDispose', Elapsed: 00:14:36
[Long Running Test] 'System.Net.Sockets.Tests.ConnectSync.ConnectGetsCanceledByDispose', Elapsed: 00:14:34
[Long Running Test] 'System.Net.Sockets.Tests.SocketOptionNameTest.MulticastInterface_Set_Loopback_Succeeds', Elapsed: 00:14:36
[Long Running Test] 'System.Net.Sockets.Tests.SendReceiveSpanSync.TcpPeerReceivesFinOnShutdownWithPendingData', Elapsed: 00:14:36
[Long Running Test] 'System.Net.Sockets.Tests.SendReceiveEap.SendAsync_ConcurrentDispose_SucceedsOrThrowsAppropriateException', Elapsed: 00:14:32
[Long Running Test] 'System.Net.Sockets.Tests.ConnectApm.ConnectGetsCanceledByDispose', Elapsed: 00:14:34
[Long Running Test] 'System.Net.Sockets.Tests.DualModeBeginConnectToIPAddress.BeginConnectV4IPAddressToV6Host_Fails', Elapsed: 00:14:24
[Long Running Test] 'System.Net.Sockets.Tests.AcceptSyncForceNonBlocking.AcceptGetsCanceledByDispose', Elapsed: 00:14:32
[Long Running Test] 'System.Net.Sockets.Tests.SendReceiveTask.SendAsync_ConcurrentDispose_SucceedsOrThrowsAppropriateException', Elapsed: 00:14:32
[Long Running Test] 'System.Net.Sockets.Tests.DualModeBeginConnect.DualModeBeginConnect_DnsEndPointToHost_Helper', Elapsed: 00:14:32
[Long Running Test] 'System.Net.Sockets.Tests.ConnectSyncForceNonBlocking.ConnectGetsCanceledByDispose', Elapsed: 00:14:24
[Long Running Test] 'System.Net.Sockets.Tests.DisposedSocket.NonDisposedSocket_SafeHandlesCollected', Elapsed: 00:14:24
[Long Running Test] 'System.Net.Sockets.Tests.AcceptTask.AcceptAsync_MultipleAcceptsThenDispose_AcceptsThrowAfterDispose', Elapsed: 00:14:24
[Long Running Test] 'System.Net.Sockets.Tests.ConnectEap.ConnectGetsCanceledByDispose', Elapsed: 00:14:24
[Long Running Test] 'System.Net.Sockets.Tests.DualModeBeginConnectToIPEndPoint.BeginConnectV6IPEndPointToV6Host_Success', Elapsed: 00:14:18
[Long Running Test] 'System.Net.Sockets.Tests.AcceptEap.AcceptGetsCanceledByDispose', Elapsed: 00:14:24
[Long Running Test] 'System.Net.Sockets.Tests.SelectAndPollTests.SelectRead_Single_Timeout', Elapsed: 00:14:10
[Long Running Test] 'System.Net.Sockets.Tests.SendReceiveSpanSyncForceNonBlocking.Receive0ByteReturns_WhenPeerDisconnects', Elapsed: 00:14:18
[Long Running Test] 'System.Net.Sockets.Tests.ConnectTask.Connect_OnConnectedSocket_Fails', Elapsed: 00:14:18
[Long Running Test] 'System.Net.Sockets.Tests.ArgumentValidation.Socket_Connect_DnsEndPointWithIPAddressString_Supported', Elapsed: 00:14:18
[Long Running Test] 'System.Net.Sockets.Tests.SelectTest.Select_ReadError_NoneReady', Elapsed: 00:14:18

@stephentoub

Copy link
Copy Markdown
Member

/azp run corefx-ci

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@tmds

tmds commented Oct 22, 2019

Copy link
Copy Markdown
Member Author

On Windows, there were missing unrefs. This is fixed and ci is now passing.
@stephentoub can you give it another run, to check if everything stays green?

@stephentoub

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 4 pipeline(s).

@stephentoub stephentoub left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks.

@stephentoub
stephentoub merged commit 6c62c7f into dotnet:master Oct 23, 2019
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
…corefx#41763)

* Socket.Select: increase ref count while the handle is in use

* PR feedback

* Use Socket.InternalSafeHandle for ref/release.

* Socket.Windows: SelectFileDescriptor: add missing unrefs


Commit migrated from dotnet/corefx@6c62c7f
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.

5 participants