Skip to content

Commit e094275

Browse files
addaleaxrvagg
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 59f1330 commit e094275

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
@@ -186,6 +186,7 @@ var parsers = new FreeList('parsers', 1000, function() {
186186
return parser;
187187
});
188188

189+
function closeParserInstance(parser) { parser.close(); }
189190

190191
// Free the parser and also break any links that it
191192
// might have to any other things.
@@ -208,7 +209,9 @@ function freeParser(parser, req, socket) {
208209
parser.outgoing = null;
209210
parser[kOnExecute] = null;
210211
if (parsers.free(parser) === false) {
211-
parser.close();
212+
// Make sure the parser's stack has unwound before deleting the
213+
// corresponding C++ object through .close().
214+
setImmediate(closeParserInstance, parser);
212215
} else {
213216
// Since the Parser destructor isn't going to run the destroy() callbacks
214217
// it needs to be triggered manually.

src/node_http_parser.cc

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

381-
if (--parser->refcount_ == 0)
382-
delete parser;
381+
delete parser;
383382
}
384383

385384

@@ -545,22 +544,6 @@ class Parser : public AsyncWrap {
545544
}
546545

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

566549
static void OnAllocImpl(size_t suggested_size, uv_buf_t* buf, void* ctx) {
@@ -597,8 +580,6 @@ class Parser : public AsyncWrap {
597580
if (nread == 0)
598581
return;
599582

600-
ScopedRetainParser retain(parser);
601-
602583
parser->current_buffer_.Clear();
603584
Local<Value> ret = parser->Execute(buf->base, nread);
604585

@@ -736,7 +717,6 @@ class Parser : public AsyncWrap {
736717
char* current_buffer_data_;
737718
StreamResource::Callback<StreamResource::AllocCb> prev_alloc_cb_;
738719
StreamResource::Callback<StreamResource::ReadCb> prev_read_cb_;
739-
int refcount_ = 1;
740720

741721
// These are helper functions for filling `http_parser_settings`, which turn
742722
// a member function of Parser into a C-style HTTP parser callback.
@@ -753,8 +733,6 @@ class Parser : public AsyncWrap {
753733
typedef int (Parser::*DataCall)(const char* at, size_t length);
754734

755735
static const struct http_parser_settings settings;
756-
757-
friend class ScopedRetainParser;
758736
};
759737

760738
const struct http_parser_settings Parser::settings = {

0 commit comments

Comments
 (0)