Skip to content

Commit 54ebf91

Browse files
addaleaxMylesBorins
authored andcommitted
http2: make sessions garbage-collectible
Use weak handles to track the lifetime of an `Http2Session` instance. Refs: nodejs/http2#140 PR-URL: #16461 Reviewed-By: Anatoli Papirovski <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Franziska Hinkelmann <[email protected]>
1 parent bfc1ad0 commit 54ebf91

File tree

4 files changed

+24
-11
lines changed

4 files changed

+24
-11
lines changed

src/node_http2.cc

+10-5
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ Http2Session::Http2Session(Environment* env,
7575
nghttp2_session_type type)
7676
: AsyncWrap(env, wrap, AsyncWrap::PROVIDER_HTTP2SESSION),
7777
StreamBase(env) {
78-
Wrap(object(), this);
78+
MakeWeak<Http2Session>(this);
7979

8080
Http2Options opts(env);
8181

@@ -102,11 +102,16 @@ Http2Session::Http2Session(Environment* env,
102102
}
103103

104104
Http2Session::~Http2Session() {
105-
CHECK_EQ(false, persistent().IsEmpty());
106-
ClearWrap(object());
105+
CHECK(persistent().IsEmpty());
106+
Close();
107+
}
108+
109+
void Http2Session::Close() {
110+
if (!object().IsEmpty())
111+
ClearWrap(object());
107112
persistent().Reset();
108-
CHECK_EQ(true, persistent().IsEmpty());
109113

114+
this->Nghttp2Session::Close();
110115
// Stop the loop
111116
CHECK_EQ(uv_prepare_stop(prep_), 0);
112117
auto prep_close = [](uv_handle_t* handle) {
@@ -407,7 +412,7 @@ void Http2Session::Destroy(const FunctionCallbackInfo<Value>& args) {
407412

408413
if (!skipUnconsume)
409414
session->Unconsume();
410-
session->Free();
415+
session->Close();
411416
}
412417

413418
void Http2Session::Destroying(const FunctionCallbackInfo<Value>& args) {

src/node_http2.h

+2
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,8 @@ class Http2Session : public AsyncWrap,
474474
return stream_buf_;
475475
}
476476

477+
void Close() override;
478+
477479
private:
478480
StreamBase* stream_;
479481
StreamResource::Callback<StreamResource::AllocCb> prev_alloc_cb_;

src/node_http2_core-inl.h

+7-5
Original file line numberDiff line numberDiff line change
@@ -587,16 +587,18 @@ inline void Nghttp2Session::MarkDestroying() {
587587
destroying_ = true;
588588
}
589589

590-
inline int Nghttp2Session::Free() {
591-
#if defined(DEBUG) && DEBUG
592-
CHECK(session_ != nullptr);
593-
#endif
590+
inline Nghttp2Session::~Nghttp2Session() {
591+
Close();
592+
}
593+
594+
inline void Nghttp2Session::Close() {
595+
if (IsClosed())
596+
return;
594597
DEBUG_HTTP2("Nghttp2Session %s: freeing session\n", TypeName());
595598
nghttp2_session_terminate_session(session_, NGHTTP2_NO_ERROR);
596599
nghttp2_session_del(session_);
597600
session_ = nullptr;
598601
DEBUG_HTTP2("Nghttp2Session %s: session freed\n", TypeName());
599-
return 1;
600602
}
601603

602604
// Write data received from the socket to the underlying nghttp2_session.

src/node_http2_core.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class Nghttp2Session {
9898
nghttp2_mem* mem = nullptr);
9999

100100
// Frees this session instance
101-
inline int Free();
101+
inline ~Nghttp2Session();
102102
inline void MarkDestroying();
103103
bool IsDestroying() {
104104
return destroying_;
@@ -141,6 +141,8 @@ class Nghttp2Session {
141141
// Returns the nghttp2 library session
142142
inline nghttp2_session* session() const { return session_; }
143143

144+
inline bool IsClosed() const { return session_ == nullptr; }
145+
144146
nghttp2_session_type type() const {
145147
return session_type_;
146148
}
@@ -202,6 +204,8 @@ class Nghttp2Session {
202204

203205
virtual uv_loop_t* event_loop() const = 0;
204206

207+
virtual void Close();
208+
205209
private:
206210
inline void HandleHeadersFrame(const nghttp2_frame* frame);
207211
inline void HandlePriorityFrame(const nghttp2_frame* frame);

0 commit comments

Comments
 (0)