Skip to content

Commit bf7dc38

Browse files
addaleaxcjihrig
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 3f52962 commit bf7dc38

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
@@ -97,7 +97,7 @@ class Nghttp2Session {
9797
nghttp2_mem* mem = nullptr);
9898

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

143+
inline bool IsClosed() const { return session_ == nullptr; }
144+
143145
nghttp2_session_type type() const {
144146
return session_type_;
145147
}
@@ -201,6 +203,8 @@ class Nghttp2Session {
201203

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

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

0 commit comments

Comments
 (0)