@@ -257,9 +257,10 @@ class Parser : public AsyncWrap, public StreamListener {
257
257
SET_SELF_SIZE(Parser)
258
258
259
259
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_
261
261
// otherwise std::set.erase will fail.
262
262
if (connectionsList_ != nullptr ) {
263
+ connectionsList_->Pop (this );
263
264
connectionsList_->PopActive (this );
264
265
}
265
266
@@ -270,6 +271,7 @@ class Parser : public AsyncWrap, public StreamListener {
270
271
status_message_.Reset ();
271
272
272
273
if (connectionsList_ != nullptr ) {
274
+ connectionsList_->Push (this );
273
275
connectionsList_->PushActive (this );
274
276
}
275
277
@@ -492,14 +494,19 @@ class Parser : public AsyncWrap, public StreamListener {
492
494
int on_message_complete () {
493
495
HandleScope scope (env ()->isolate ());
494
496
495
- // Important: Pop from the list BEFORE resetting the last_message_start_
497
+ // Important: Pop from the lists BEFORE resetting the last_message_start_
496
498
// otherwise std::set.erase will fail.
497
499
if (connectionsList_ != nullptr ) {
500
+ connectionsList_->Pop (this );
498
501
connectionsList_->PopActive (this );
499
502
}
500
503
501
504
last_message_start_ = 0 ;
502
505
506
+ if (connectionsList_ != nullptr ) {
507
+ connectionsList_->Push (this );
508
+ }
509
+
503
510
if (num_fields_)
504
511
Flush (); // Flush trailing HTTP headers.
505
512
@@ -666,12 +673,14 @@ class Parser : public AsyncWrap, public StreamListener {
666
673
if (connectionsList != nullptr ) {
667
674
parser->connectionsList_ = connectionsList;
668
675
669
- parser->connectionsList_ ->Push (parser);
670
-
671
676
// This protects from a DoS attack where an attacker establishes
672
677
// the connection without sending any data on applications where
673
678
// server.timeout is left to the default value of zero.
674
679
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);
675
684
parser->connectionsList_ ->PushActive (parser);
676
685
} else {
677
686
parser->connectionsList_ = nullptr ;
@@ -1044,10 +1053,14 @@ class Parser : public AsyncWrap, public StreamListener {
1044
1053
};
1045
1054
1046
1055
bool 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 ) {
1050
1061
return true ;
1062
+ } else if (rhs->last_message_start_ == 0 ) {
1063
+ return false ;
1051
1064
}
1052
1065
1053
1066
return lhs->last_message_start_ < rhs->last_message_start_ ;
0 commit comments