-
Notifications
You must be signed in to change notification settings - Fork 844
Delete H2 stream before destroy #2774
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
Conversation
proxy/http2/Http2Stream.cc
Outdated
| if (terminate_stream && reentrancy_count == 0) { | ||
| Http2ClientSession *h2_parent = static_cast<Http2ClientSession *>(parent); | ||
| SCOPED_MUTEX_LOCK(lock, h2_parent->connection_state.mutex, this_ethread()); | ||
| h2_parent->connection_state.delete_stream(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These block looks similar to L667-L681 ( Http2Stream::destroy() ).
trafficserver/proxy/http2/Http2Stream.cc
Lines 667 to 681 in 6dcc822
| // release_stream and delete_stream indirectly call each other and seem to have a lot of commonality | |
| // Should get resolved at somepoint. | |
| Http2ClientSession *h2_parent = static_cast<Http2ClientSession *>(parent); | |
| SCOPED_MUTEX_LOCK(lock, h2_parent->connection_state.mutex, this_ethread()); | |
| h2_parent->connection_state.release_stream(this); | |
| // Current Http2ConnectionState implementation uses a memory pool for instantiating streams and DLL<> stream_list for storing | |
| // active streams. Destroying a stream before deleting it from stream_list and then creating a new one + reusing the same chunk | |
| // from the memory pool right away always leads to destroying the DLL structure (deadlocks, inconsistencies). | |
| // The following is meant as a safety net since the consequences are disastrous. Until the design/implementation changes it | |
| // seems | |
| // less error prone to (double) delete before destroying (noop if already deleted). | |
| if (h2_parent->connection_state.delete_stream(this)) { | |
| Warning("Http2Stream was about to be deallocated without removing it from the active stream list"); | |
| } |
How about calling
delete_stream() before release_stream() in Http2Stream::destroy() ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the block in destroy() is a part of safety net. That may strengthen the safety net, however, I think destroy should do only destroying, and we shouldn't depend on the safety net.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I agree that the delete_stream/release_stream/destroy relationship isn't very satisfying. I'll look a bit, and see if we can unify things a bit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a different fix that I'm running on a prod box for 30 minutes (a new record!). I made a change in release_stream. It was removing the stream from the connection_state. This means that the actual delete_stream would exit immediately without cleaning up the priority tree.
I must run out right now, but I'll put up another PR later this evening. Assuming the prod box doesn't go crazy before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My fix is in PR #2781
|
[approve ci autest] |
07d7d02 to
1ac7ff9
Compare
1ac7ff9 to
6c4d9ac
Compare
|
Testing on Docs now. |
|
Cherry-picked to 7.1.2. |
delete_stream()removes a stream frompriority_tree, but here, the stream destroy itself without callingdelete_stream(). The stream can be used during processingHTTP2_SESSION_EVENT_XMIT.I think this fixes #2207.