@@ -257,9 +257,10 @@ class Parser : public AsyncWrap, public StreamListener {
257257 SET_SELF_SIZE(Parser)
258258
259259 int on_message_begin() {
260- // Important: Pop from the list BEFORE resetting the last_message_start_
260+ // Important: Pop from the lists BEFORE resetting the last_message_start_
261261 // otherwise std::set.erase will fail.
262262 if (connectionsList_ != nullptr ) {
263+ connectionsList_->Pop (this );
263264 connectionsList_->PopActive (this );
264265 }
265266
@@ -270,6 +271,7 @@ class Parser : public AsyncWrap, public StreamListener {
270271 status_message_.Reset ();
271272
272273 if (connectionsList_ != nullptr ) {
274+ connectionsList_->Push (this );
273275 connectionsList_->PushActive (this );
274276 }
275277
@@ -492,14 +494,19 @@ class Parser : public AsyncWrap, public StreamListener {
492494 int on_message_complete () {
493495 HandleScope scope (env ()->isolate ());
494496
495- // Important: Pop from the list BEFORE resetting the last_message_start_
497+ // Important: Pop from the lists BEFORE resetting the last_message_start_
496498 // otherwise std::set.erase will fail.
497499 if (connectionsList_ != nullptr ) {
500+ connectionsList_->Pop (this );
498501 connectionsList_->PopActive (this );
499502 }
500503
501504 last_message_start_ = 0 ;
502505
506+ if (connectionsList_ != nullptr ) {
507+ connectionsList_->Push (this );
508+ }
509+
503510 if (num_fields_)
504511 Flush (); // Flush trailing HTTP headers.
505512
@@ -666,12 +673,14 @@ class Parser : public AsyncWrap, public StreamListener {
666673 if (connectionsList != nullptr ) {
667674 parser->connectionsList_ = connectionsList;
668675
669- parser->connectionsList_ ->Push (parser);
670-
671676 // This protects from a DoS attack where an attacker establishes
672677 // the connection without sending any data on applications where
673678 // server.timeout is left to the default value of zero.
674679 parser->last_message_start_ = uv_hrtime ();
680+
681+ // Important: Push into the lists AFTER setting the last_message_start_
682+ // otherwise std::set.erase will fail later.
683+ parser->connectionsList_ ->Push (parser);
675684 parser->connectionsList_ ->PushActive (parser);
676685 } else {
677686 parser->connectionsList_ = nullptr ;
@@ -1044,10 +1053,14 @@ class Parser : public AsyncWrap, public StreamListener {
10441053};
10451054
10461055bool ParserComparator::operator ()(const Parser* lhs, const Parser* rhs) const {
1047- if (lhs->last_message_start_ == 0 ) {
1048- return false ;
1049- } else if (rhs->last_message_start_ == 0 ) {
1056+ if (lhs->last_message_start_ == 0 && rhs->last_message_start_ == 0 ) {
1057+ // When both parsers are idle, guarantee strict order by
1058+ // comparing pointers as ints.
1059+ return lhs < rhs;
1060+ } else if (lhs->last_message_start_ == 0 ) {
10501061 return true ;
1062+ } else if (rhs->last_message_start_ == 0 ) {
1063+ return false ;
10511064 }
10521065
10531066 return lhs->last_message_start_ < rhs->last_message_start_ ;
0 commit comments