gfe-relnote: only respect TLPR when there is pending non-crypto stream data. Flag protected by quic_ignore_tlpr_if_no_pending_stream_data and session_decides_what_to_write.

When calculating the tail loss probe delay and TLPR option is enabled, only use half tail loss probe when session has pending stream data. Otherwise, ignore TLPR.

PiperOrigin-RevId: 253286073
Change-Id: I9321c9d0608f68bb4ec0f7f4fbba1e470e4a0a3c
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc
index 33b9ddb..1e863b1 100644
--- a/quic/core/quic_session.cc
+++ b/quic/core/quic_session.cc
@@ -8,9 +8,11 @@
 #include <string>
 #include <utility>
 
+#include "base/logging.h"
 #include "net/third_party/quiche/src/quic/core/quic_connection.h"
 #include "net/third_party/quiche/src/quic/core/quic_flow_controller.h"
 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/core/quic_versions.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
@@ -869,6 +871,13 @@
   if (stream->IsWaitingForAcks()) {
     zombie_streams_[stream->id()] = std::move(it->second);
   } else {
+    // Clean up the stream since it is no longer waiting for acks.
+    if (ignore_tlpr_if_no_pending_stream_data() &&
+        session_decides_what_to_write()) {
+      QUIC_RELOADABLE_FLAG_COUNT_N(quic_ignore_tlpr_if_no_pending_stream_data,
+                                   2, 5);
+      streams_waiting_for_acks_.erase(stream->id());
+    }
     closed_streams_.push_back(std::move(it->second));
     // Do not retransmit data of a closed stream.
     streams_with_pending_retransmission_.erase(stream_id);
@@ -1543,6 +1552,13 @@
 }
 
 void QuicSession::OnStreamDoneWaitingForAcks(QuicStreamId id) {
+  if (ignore_tlpr_if_no_pending_stream_data() &&
+      session_decides_what_to_write()) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_ignore_tlpr_if_no_pending_stream_data, 3,
+                                 5);
+    streams_waiting_for_acks_.erase(id);
+  }
+
   auto it = zombie_streams_.find(id);
   if (it == zombie_streams_.end()) {
     return;
@@ -1557,6 +1573,34 @@
   streams_with_pending_retransmission_.erase(id);
 }
 
+void QuicSession::OnStreamWaitingForAcks(QuicStreamId id) {
+  if (!ignore_tlpr_if_no_pending_stream_data() ||
+      !session_decides_what_to_write())
+    return;
+
+  // Exclude crypto stream's status since it is counted in HasUnackedCryptoData.
+  if (GetCryptoStream() != nullptr && id == GetCryptoStream()->id()) {
+    return;
+  }
+
+  QUIC_RELOADABLE_FLAG_COUNT_N(quic_ignore_tlpr_if_no_pending_stream_data, 4,
+                               5);
+  streams_waiting_for_acks_.insert(id);
+
+  // The number of the streams waiting for acks should not be larger than the
+  // number of streams.
+  if (dynamic_stream_map_.size() + static_stream_map_.size() +
+          zombie_streams_.size() <
+      static_cast<int>(streams_waiting_for_acks_.size())) {
+    QUIC_BUG << "More streams are waiting for acks than the number of streams. "
+             << "Sizes: dynamic streams: " << dynamic_stream_map_.size()
+             << ", static streams: " << static_stream_map_.size()
+             << ", zombie streams: " << zombie_streams_.size()
+             << ", vs streams waiting for acks: "
+             << streams_waiting_for_acks_.size();
+  }
+}
+
 QuicStream* QuicSession::GetStream(QuicStreamId id) const {
   if (id <= largest_static_stream_id_) {
     auto static_stream = static_stream_map_.find(id);
@@ -1716,6 +1760,17 @@
   return false;
 }
 
+bool QuicSession::HasUnackedStreamData() const {
+  DCHECK(ignore_tlpr_if_no_pending_stream_data());
+  if (ignore_tlpr_if_no_pending_stream_data()) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_ignore_tlpr_if_no_pending_stream_data, 5,
+                                 5);
+    return !streams_waiting_for_acks_.empty();
+  }
+
+  return true;
+}
+
 WriteStreamDataResult QuicSession::WriteStreamData(QuicStreamId id,
                                                    QuicStreamOffset offset,
                                                    QuicByteCount data_length,