summaryrefslogtreecommitdiffstats
path: root/net/quic
diff options
context:
space:
mode:
authorrch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-14 23:31:17 +0000
committerrch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-14 23:31:17 +0000
commit516f6f88bc0334651fbc9a8d861983318fd30fa5 (patch)
tree5312777a0585544f0af30facdb8286a67d8f0193 /net/quic
parentd3ae9ed4e3d0e7fa0c85eec1ca73f317e78d927f (diff)
downloadchromium_src-516f6f88bc0334651fbc9a8d861983318fd30fa5.zip
chromium_src-516f6f88bc0334651fbc9a8d861983318fd30fa5.tar.gz
chromium_src-516f6f88bc0334651fbc9a8d861983318fd30fa5.tar.bz2
Switching from many small alarms to one big alarm for QUIC resends.
Merge internal change: 40296535 BUG= Review URL: https://chromiumcodereview.appspot.com/11821008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@176757 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/quic')
-rw-r--r--net/quic/quic_connection_helper.cc56
-rw-r--r--net/quic/quic_connection_helper.h8
2 files changed, 53 insertions, 11 deletions
diff --git a/net/quic/quic_connection_helper.cc b/net/quic/quic_connection_helper.cc
index 16d2782..bf10619 100644
--- a/net/quic/quic_connection_helper.cc
+++ b/net/quic/quic_connection_helper.cc
@@ -15,6 +15,10 @@
namespace net {
+// Limit the number of packets we send per resend-alarm so we eventually cede.
+// 10 is arbitrary.
+const size_t kMaxPacketsPerResendAlarm = 10;
+
QuicConnectionHelper::QuicConnectionHelper(base::TaskRunner* task_runner,
const QuicClock* clock,
QuicRandom* random_generator,
@@ -25,7 +29,9 @@ QuicConnectionHelper::QuicConnectionHelper(base::TaskRunner* task_runner,
clock_(clock),
random_generator_(random_generator),
send_alarm_registered_(false),
- timeout_alarm_registered_(false) {
+ timeout_alarm_registered_(false),
+ resend_alarm_registered_(false),
+ resend_alarm_running_(false) {
}
QuicConnectionHelper::~QuicConnectionHelper() {
@@ -70,12 +76,16 @@ int QuicConnectionHelper::WritePacketToWire(
void QuicConnectionHelper::SetResendAlarm(
QuicPacketSequenceNumber sequence_number,
QuicTime::Delta delay) {
- // TODO(rch): Coalesce these alarms.
- task_runner_->PostDelayedTask(
- FROM_HERE,
- base::Bind(&QuicConnectionHelper::OnResendAlarm,
- weak_factory_.GetWeakPtr(), sequence_number),
- base::TimeDelta::FromMicroseconds(delay.ToMicroseconds()));
+ if (!resend_alarm_registered_ &&
+ !resend_alarm_running_) {
+ resend_alarm_registered_ = true;
+ task_runner_->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&QuicConnectionHelper::OnResendAlarm,
+ weak_factory_.GetWeakPtr()),
+ base::TimeDelta::FromMicroseconds(delay.ToMicroseconds()));
+ }
+ resend_times_[sequence_number] = clock_->Now().Add(delay);
}
void QuicConnectionHelper::SetSendAlarm(QuicTime::Delta delay) {
@@ -118,10 +128,36 @@ void QuicConnectionHelper::GetPeerAddress(IPEndPoint* peer_address) {
socket_->GetPeerAddress(peer_address);
}
+void QuicConnectionHelper::OnResendAlarm() {
+ // This guards against registering the alarm later than we should.
+ //
+ // If we have packet A and B in the list and we call MaybeResendPacket on
+ // A, that may trigger a call to SetResendAlarm if A is resent as C. In
+ // that case we don't want to register the alarm under SetResendAlarm; we
+ // want to set it to the RTO of B at the end of this method.
+ resend_alarm_registered_ = false;
+ resend_alarm_running_ = true;
+
+ for (size_t i = 0; i < kMaxPacketsPerResendAlarm; ++i) {
+ if (resend_times_.empty() ||
+ resend_times_.begin()->second > clock_->Now()) {
+ break;
+ }
+ QuicPacketSequenceNumber sequence_number = resend_times_.begin()->first;
+ connection_->MaybeResendPacket(sequence_number);
+ resend_times_.erase(sequence_number);
+ }
+
+ // Nothing from here on does external calls.
+ resend_alarm_running_ = false;
+ if (resend_times_.empty()) {
+ return;
+ }
-void QuicConnectionHelper::OnResendAlarm(
- QuicPacketSequenceNumber sequence_number) {
- connection_->MaybeResendPacket(sequence_number);
+ // We have packet remaining. Reschedule for the RTO of the oldest packet
+ // on the list.
+ SetResendAlarm(resend_times_.begin()->first,
+ resend_times_.begin()->second.Subtract(clock_->Now()));
}
void QuicConnectionHelper::OnSendAlarm() {
diff --git a/net/quic/quic_connection_helper.h b/net/quic/quic_connection_helper.h
index 22585ae..5e1c46e 100644
--- a/net/quic/quic_connection_helper.h
+++ b/net/quic/quic_connection_helper.h
@@ -65,7 +65,7 @@ class NET_EXPORT_PRIVATE QuicConnectionHelper
// An alarm is scheduled for each data-bearing packet as it is sent out.
// When the alarm goes off, the connection checks to see if the packet has
// been acked, and resends if it has not.
- void OnResendAlarm(QuicPacketSequenceNumber sequence_number);
+ void OnResendAlarm();
// An alarm that is scheduled when the sent scheduler requires a
// a delay before sending packets and fires when the packet may be sent.
void OnSendAlarm();
@@ -73,6 +73,8 @@ class NET_EXPORT_PRIVATE QuicConnectionHelper
void OnTimeoutAlarm();
// A completion callback invoked when a write completes.
void OnWriteComplete(int result);
+ // An alarm which fires if we've hit a timeout on sending an ack.
+ void OnAckAlarm();
base::WeakPtrFactory<QuicConnectionHelper> weak_factory_;
base::TaskRunner* task_runner_;
@@ -82,6 +84,10 @@ class NET_EXPORT_PRIVATE QuicConnectionHelper
QuicRandom* random_generator_;
bool send_alarm_registered_;
bool timeout_alarm_registered_;
+ bool resend_alarm_registered_;
+ bool resend_alarm_running_;
+ // Times that packets should be resent.
+ std::map<QuicPacketSequenceNumber, QuicTime> resend_times_;
DISALLOW_COPY_AND_ASSIGN(QuicConnectionHelper);
};