Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion lib/_http_common.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,9 @@ function freeParser(parser, req, socket) {
parser.outgoing = null;
parser[kOnExecute] = null;
if (parsers.free(parser) === false) {
parser.close();
// Make sure the parser's stack has unwound before deleting the
// corresponding C++ object through .close().
setImmediate((parser) => parser.close(), parser);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's trivial, but can you make this a top level function instead of allocating the closure?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make much of a difference if it’s not a closure? I would expect engines to optimize that away?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like, yes, I can do that, I’m just curious whether it makes any difference.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it makes a difference. In this case it would likely be trivial but it definitely has an impact. The engines do not optimize away the closures at this point

} else {
// Since the Parser destructor isn't going to run the destroy() callbacks
// it needs to be triggered manually.
Expand Down
24 changes: 1 addition & 23 deletions src/node_http_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,7 @@ class Parser : public AsyncWrap {
Parser* parser;
ASSIGN_OR_RETURN_UNWRAP(&parser, args.Holder());

if (--parser->refcount_ == 0)
delete parser;
delete parser;
}


Expand Down Expand Up @@ -559,22 +558,6 @@ class Parser : public AsyncWrap {
}

protected:
class ScopedRetainParser {
public:
explicit ScopedRetainParser(Parser* p) : p_(p) {
CHECK_GT(p_->refcount_, 0);
p_->refcount_++;
}

~ScopedRetainParser() {
if (0 == --p_->refcount_)
delete p_;
}

private:
Parser* const p_;
};

static const size_t kAllocBufferSize = 64 * 1024;

static void OnAllocImpl(size_t suggested_size, uv_buf_t* buf, void* ctx) {
Expand Down Expand Up @@ -611,8 +594,6 @@ class Parser : public AsyncWrap {
if (nread == 0)
return;

ScopedRetainParser retain(parser);

parser->current_buffer_.Clear();
Local<Value> ret = parser->Execute(buf->base, nread);

Expand Down Expand Up @@ -750,10 +731,7 @@ class Parser : public AsyncWrap {
char* current_buffer_data_;
StreamResource::Callback<StreamResource::AllocCb> prev_alloc_cb_;
StreamResource::Callback<StreamResource::ReadCb> prev_read_cb_;
int refcount_ = 1;
static const struct http_parser_settings settings;

friend class ScopedRetainParser;
};


Expand Down