Skip to content

Commit 97775f1

Browse files
addaleaxevanlucas
authored andcommitted
http: simplify parser lifetime tracking
Instead of providing a separate class for keeping the parser alive during its own call back, just delay a possible `.close()` call until the stack has cleared completely. PR-URL: #18135 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Franziska Hinkelmann <[email protected]> Reviewed-By: Anatoli Papirovski <[email protected]> Reviewed-By: Colin Ihrig <[email protected]>
1 parent e22602f commit 97775f1

File tree

2 files changed

+5
-24
lines changed

2 files changed

+5
-24
lines changed

lib/_http_common.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ var parsers = new FreeList('parsers', 1000, function() {
190190
return parser;
191191
});
192192

193+
function closeParserInstance(parser) { parser.close(); }
193194

194195
// Free the parser and also break any links that it
195196
// might have to any other things.
@@ -212,7 +213,9 @@ function freeParser(parser, req, socket) {
212213
parser.outgoing = null;
213214
parser[kOnExecute] = null;
214215
if (parsers.free(parser) === false) {
215-
parser.close();
216+
// Make sure the parser's stack has unwound before deleting the
217+
// corresponding C++ object through .close().
218+
setImmediate(closeParserInstance, parser);
216219
} else {
217220
// Since the Parser destructor isn't going to run the destroy() callbacks
218221
// it needs to be triggered manually.

src/node_http_parser.cc

+1-23
Original file line numberDiff line numberDiff line change
@@ -376,8 +376,7 @@ class Parser : public AsyncWrap {
376376
Parser* parser;
377377
ASSIGN_OR_RETURN_UNWRAP(&parser, args.Holder());
378378

379-
if (--parser->refcount_ == 0)
380-
delete parser;
379+
delete parser;
381380
}
382381

383382

@@ -543,22 +542,6 @@ class Parser : public AsyncWrap {
543542
}
544543

545544
protected:
546-
class ScopedRetainParser {
547-
public:
548-
explicit ScopedRetainParser(Parser* p) : p_(p) {
549-
CHECK_GT(p_->refcount_, 0);
550-
p_->refcount_++;
551-
}
552-
553-
~ScopedRetainParser() {
554-
if (0 == --p_->refcount_)
555-
delete p_;
556-
}
557-
558-
private:
559-
Parser* const p_;
560-
};
561-
562545
static const size_t kAllocBufferSize = 64 * 1024;
563546

564547
static void OnAllocImpl(size_t suggested_size, uv_buf_t* buf, void* ctx) {
@@ -595,8 +578,6 @@ class Parser : public AsyncWrap {
595578
if (nread == 0)
596579
return;
597580

598-
ScopedRetainParser retain(parser);
599-
600581
parser->current_buffer_.Clear();
601582
Local<Value> ret = parser->Execute(buf->base, nread);
602583

@@ -734,7 +715,6 @@ class Parser : public AsyncWrap {
734715
char* current_buffer_data_;
735716
StreamResource::Callback<StreamResource::AllocCb> prev_alloc_cb_;
736717
StreamResource::Callback<StreamResource::ReadCb> prev_read_cb_;
737-
int refcount_ = 1;
738718

739719
// These are helper functions for filling `http_parser_settings`, which turn
740720
// a member function of Parser into a C-style HTTP parser callback.
@@ -751,8 +731,6 @@ class Parser : public AsyncWrap {
751731
typedef int (Parser::*DataCall)(const char* at, size_t length);
752732

753733
static const struct http_parser_settings settings;
754-
755-
friend class ScopedRetainParser;
756734
};
757735

758736
const struct http_parser_settings Parser::settings = {

0 commit comments

Comments
 (0)