Move the implementation of GetReleaseTime from QuicBatchWriterBase to QuicGsoBatchWriter. No behavior change.

This makes it easier to modify the GetReleaseTime function in multi release mode.

PiperOrigin-RevId: 327089872
Change-Id: I6d52a40324290017657eef3f2d9bef4e54b8e914
diff --git a/quic/core/batch_writer/quic_batch_writer_base.cc b/quic/core/batch_writer/quic_batch_writer_base.cc
index 51b6188..ade94a7 100644
--- a/quic/core/batch_writer/quic_batch_writer_base.cc
+++ b/quic/core/batch_writer/quic_batch_writer_base.cc
@@ -8,7 +8,6 @@
 #include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_server_stats.h"
 
 namespace quic {
 
@@ -30,52 +29,6 @@
   return result;
 }
 
-QuicBatchWriterBase::ReleaseTime QuicBatchWriterBase::GetReleaseTime(
-    const PerPacketOptions* options) const {
-  DCHECK(SupportsReleaseTime());
-
-  if (options == nullptr) {
-    return {0, QuicTime::Delta::Zero()};
-  }
-
-  const uint64_t now = NowInNanosForReleaseTime();
-  const uint64_t ideal_release_time =
-      now + options->release_time_delay.ToMicroseconds() * 1000;
-
-  if ((options->release_time_delay.IsZero() || options->allow_burst) &&
-      !buffered_writes().empty() &&
-      // If release time of buffered packets is in the past, flush buffered
-      // packets and buffer this packet at the ideal release time.
-      (buffered_writes().back().release_time >= now)) {
-    // Send as soon as possible, but no sooner than the last buffered packet.
-    const uint64_t actual_release_time = buffered_writes().back().release_time;
-
-    const int64_t offset_ns = actual_release_time - ideal_release_time;
-    if (offset_ns >= 0) {
-      QUIC_SERVER_HISTOGRAM_TIMES("batch_writer_positive_release_time_offset",
-                                  offset_ns / 1000, 1, 100000, 50,
-                                  "Duration from ideal release time to actual "
-                                  "release time, in microseconds.");
-    } else {
-      QUIC_SERVER_HISTOGRAM_TIMES("batch_writer_negative_release_time_offset",
-                                  -offset_ns / 1000, 1, 100000, 50,
-                                  "Duration from actual release time to ideal "
-                                  "release time, in microseconds.");
-    }
-
-    ReleaseTime result{actual_release_time,
-                       QuicTime::Delta::FromMicroseconds(offset_ns / 1000)};
-
-    QUIC_DVLOG(1) << "ideal_release_time:" << ideal_release_time
-                  << ", actual_release_time:" << actual_release_time
-                  << ", offset:" << result.release_time_offset;
-    return result;
-  }
-
-  // Send according to the release time delay.
-  return {ideal_release_time, QuicTime::Delta::Zero()};
-}
-
 WriteResult QuicBatchWriterBase::InternalWritePacket(
     const char* buffer,
     size_t buf_len,
diff --git a/quic/core/batch_writer/quic_batch_writer_base.h b/quic/core/batch_writer/quic_batch_writer_base.h
index b902677..30e1af4 100644
--- a/quic/core/batch_writer/quic_batch_writer_base.h
+++ b/quic/core/batch_writer/quic_batch_writer_base.h
@@ -64,13 +64,6 @@
     return batch_buffer_->buffered_writes();
   }
 
-  // Get the current time in nanos which is understood by the sending api for
-  // releasing packets in the future.
-  virtual uint64_t NowInNanosForReleaseTime() const {
-    DCHECK(false) << "Should not be called since release time is unsupported.";
-    return 0;
-  }
-
   // Given the release delay in |options| and the state of |batch_buffer_|, get
   // the absolute release time.
   struct QUIC_NO_EXPORT ReleaseTime {
@@ -80,7 +73,11 @@
     // which is (now + |options->release_time_delay|).
     QuicTime::Delta release_time_offset = QuicTime::Delta::Zero();
   };
-  ReleaseTime GetReleaseTime(const PerPacketOptions* options) const;
+  virtual ReleaseTime GetReleaseTime(
+      const PerPacketOptions* /*options*/) const {
+    DCHECK(false) << "Should not be called since release time is unsupported.";
+    return ReleaseTime{0, QuicTime::Delta::Zero()};
+  }
 
   struct QUIC_EXPORT_PRIVATE CanBatchResult {
     CanBatchResult(bool can_batch, bool must_flush)
diff --git a/quic/core/batch_writer/quic_gso_batch_writer.cc b/quic/core/batch_writer/quic_gso_batch_writer.cc
index 95db178..5feb595 100644
--- a/quic/core/batch_writer/quic_gso_batch_writer.cc
+++ b/quic/core/batch_writer/quic_gso_batch_writer.cc
@@ -8,6 +8,7 @@
 #include <ctime>
 
 #include "net/third_party/quiche/src/quic/core/quic_linux_socket_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_server_stats.h"
 
 namespace quic {
 
@@ -96,6 +97,52 @@
   return CanBatchResult(can_batch, must_flush);
 }
 
+QuicGsoBatchWriter::ReleaseTime QuicGsoBatchWriter::GetReleaseTime(
+    const PerPacketOptions* options) const {
+  DCHECK(SupportsReleaseTime());
+
+  if (options == nullptr) {
+    return {0, QuicTime::Delta::Zero()};
+  }
+
+  const uint64_t now = NowInNanosForReleaseTime();
+  const uint64_t ideal_release_time =
+      now + options->release_time_delay.ToMicroseconds() * 1000;
+
+  if ((options->release_time_delay.IsZero() || options->allow_burst) &&
+      !buffered_writes().empty() &&
+      // If release time of buffered packets is in the past, flush buffered
+      // packets and buffer this packet at the ideal release time.
+      (buffered_writes().back().release_time >= now)) {
+    // Send as soon as possible, but no sooner than the last buffered packet.
+    const uint64_t actual_release_time = buffered_writes().back().release_time;
+
+    const int64_t offset_ns = actual_release_time - ideal_release_time;
+    if (offset_ns >= 0) {
+      QUIC_SERVER_HISTOGRAM_TIMES("gso_writer_positive_release_time_offset",
+                                  offset_ns / 1000, 1, 100000, 50,
+                                  "Duration from ideal release time to actual "
+                                  "release time, in microseconds.");
+    } else {
+      QUIC_SERVER_HISTOGRAM_TIMES("gso_writer_negative_release_time_offset",
+                                  -offset_ns / 1000, 1, 100000, 50,
+                                  "Duration from actual release time to ideal "
+                                  "release time, in microseconds.");
+    }
+
+    ReleaseTime result{actual_release_time,
+                       QuicTime::Delta::FromMicroseconds(offset_ns / 1000)};
+
+    QUIC_DVLOG(1) << "ideal_release_time:" << ideal_release_time
+                  << ", actual_release_time:" << actual_release_time
+                  << ", offset:" << result.release_time_offset;
+    return result;
+  }
+
+  // Send according to the release time delay.
+  return {ideal_release_time, QuicTime::Delta::Zero()};
+}
+
 uint64_t QuicGsoBatchWriter::NowInNanosForReleaseTime() const {
   struct timespec ts;
 
diff --git a/quic/core/batch_writer/quic_gso_batch_writer.h b/quic/core/batch_writer/quic_gso_batch_writer.h
index d210cf7..ce8a71d 100644
--- a/quic/core/batch_writer/quic_gso_batch_writer.h
+++ b/quic/core/batch_writer/quic_gso_batch_writer.h
@@ -41,7 +41,10 @@
                      clockid_t clockid_for_release_time,
                      ReleaseTimeForceEnabler enabler);
 
-  uint64_t NowInNanosForReleaseTime() const override;
+  ReleaseTime GetReleaseTime(const PerPacketOptions* options) const override;
+
+  // Get the current time in nanos from |clockid_for_release_time_|.
+  virtual uint64_t NowInNanosForReleaseTime() const;
 
   static size_t MaxSegments(size_t gso_size) {
     // Max segments should be the min of UDP_MAX_SEGMENTS(64) and