-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
QUIC: Should not need finalization on MsQuicStream/Connection/Listener #55103
Comments
Tagging subscribers to this area: @dotnet/ncl Issue DetailsCurrently we have a chain of objects for each of Stream/Connection/Listener that looks like this: MsQuicStream (finalizable) -> stream State object (rooted by GCHandle) -> SafeMsQuicStreamHandle (finalizable) We shouldn't need MsQuicStream to be finalizable; we should be able to rely on the SafeHandle finalizer -- after all that's what it is for. The reason we need this today is that msquic holds a GCHandle to the State object, which roots it until the msquic stream handle is closed and all events are processed. But the State object holds a ref to the SafeHandle, which means the SafeHandle itself will never be finalized. We use the finalizer on MsQuicStream to break this loop. I think we can solve this by removing the reference from State to the SafeHandle. In general we shouldn't need this; the MsQuicStream can pass the handle into appropriate methods on State when necessary. So: MsQuicStream -> stream State object (rooted by GCHandle)
|
AFAIU This could be solved differently as well. We had a chat with @wfurt about |
But if I understand correctly, changing to |
To be explicit: the issue re refcounting streams on a connection is that all msquic stream handles must be closed before the connection handle is closed. I think it would be best to handle this by having the stream SafeHandle take a DangerousAddRef on the connection SafeHandle. This should enable us to remove the refcounting that exists on MsQuicConnection today. That said, this is not a priority relative to other issues we have at the moment. |
CR: We could laverage DangerousAddRef to handle relation between connection and stream and properly order calls to close. |
That is not true - I've checked it now. If I hold a reference to a stream (prevent Close on stream's SafeHandle) and then call Shutdown on the connection (CloseAsync() in S.N.Quic API), I do receive SHUTDOWN_COMPLETE event on that connection, even though the stream handle is "alive", meaning it is still not safe to close connection's SafeHandle. |
can you please comment on this @nibanks? That seems to contradict what we talk about. |
Triage: This is sensitive area which already destabilized us before. Right now we are stable based on our test runs. Moving to 7.0. |
Triage: We should do it early in 7.0 to have time to stabilize. We have decent test coverage now, so we are not too much afraid to touch it. |
Currently we have a chain of objects for each of Stream/Connection/Listener that looks like this:
MsQuicStream (finalizable) -> stream State object (rooted by GCHandle) -> SafeMsQuicStreamHandle (finalizable)
We shouldn't need MsQuicStream to be finalizable; we should be able to rely on the SafeHandle finalizer -- after all that's what it is for.
The reason we need this today is that msquic holds a GCHandle to the State object, which roots it until the msquic stream handle is closed and all events are processed. But the State object holds a ref to the SafeHandle, which means the SafeHandle itself will never be finalized. We use the finalizer on MsQuicStream to break this loop.
I think we can solve this by removing the reference from State to the SafeHandle. In general we shouldn't need this; the MsQuicStream can pass the handle into appropriate methods on State when necessary.
So:
MsQuicStream -> stream State object (rooted by GCHandle)
MsQuicStream -> SafeMsQuicStreamHandle (finalizable)
The text was updated successfully, but these errors were encountered: