Skip to content

Commit 55f6bdb

Browse files
addaleaxMylesBorins
authored andcommitted
http2: keep session objects alive during Http2Scope
Keep a local handle as a reference to the JS `Http2Session` object so that it will not be garbage collected when inside an `Http2Scope`, because the presence of the latter usually indicates that further actions on the session object are expected. Strictly speaking, storing the `session_handle_` as a property on the scope object is not necessary, but this is not very costly and makes the code more obviously correct. Fixes: #17840 Backport-PR-URL: #18050 Backport-PR-URL: #20456 PR-URL: #17863 Fixes: #17840 Reviewed-By: Anatoli Papirovski <apapirovski@mac.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
1 parent c61a54e commit 55f6bdb

File tree

3 files changed

+19
-0
lines changed

3 files changed

+19
-0
lines changed

src/node_http2.cc

+7
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ Http2Scope::Http2Scope(Http2Session* session) {
7171
}
7272
session->flags_ |= SESSION_STATE_HAS_SCOPE;
7373
session_ = session;
74+
75+
// Always keep the session object alive for at least as long as
76+
// this scope is active.
77+
session_handle_ = session->object();
78+
CHECK(!session_handle_.IsEmpty());
7479
}
7580

7681
Http2Scope::~Http2Scope() {
@@ -512,6 +517,7 @@ void Http2Session::Unconsume() {
512517
}
513518

514519
Http2Session::~Http2Session() {
520+
CHECK_EQ(flags_ & SESSION_STATE_HAS_SCOPE, 0);
515521
if (!object().IsEmpty())
516522
ClearWrap(object());
517523
persistent().Reset();
@@ -1365,6 +1371,7 @@ void Http2Session::OnStreamReadImpl(ssize_t nread,
13651371
void* ctx) {
13661372
Http2Session* session = static_cast<Http2Session*>(ctx);
13671373
Http2Scope h2scope(session);
1374+
CHECK_NE(session->stream_, nullptr);
13681375
DEBUG_HTTP2SESSION2(session, "receiving %d bytes", nread);
13691376
if (nread < 0) {
13701377
uv_buf_t tmp_buf;

src/node_http2.h

+1
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ class Http2Scope {
444444

445445
private:
446446
Http2Session* session_ = nullptr;
447+
Local<Object> session_handle_;
447448
};
448449

449450
// The Http2Options class is used to parse the options object passed in to

test/parallel/test-http2-createwritereq.js

+11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
'use strict';
22

3+
// Flags: --expose-gc
4+
35
const common = require('../common');
46
if (!common.hasCrypto)
57
common.skip('missing crypto');
@@ -62,6 +64,15 @@ server.listen(0, common.mustCall(function() {
6264
}
6365
}));
6466

67+
// Ref: https://github.com/nodejs/node/issues/17840
68+
const origDestroy = req.destroy;
69+
req.destroy = function(...args) {
70+
// Schedule a garbage collection event at the end of the current
71+
// MakeCallback() run.
72+
process.nextTick(global.gc);
73+
return origDestroy.call(this, ...args);
74+
};
75+
6576
req.end();
6677
});
6778
}));

0 commit comments

Comments
 (0)