| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/base/backoff_entry.h" | 5 #include "net/base/backoff_entry.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <limits> | 9 #include <limits> |
| 10 | 10 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 void BackoffEntry::SetCustomReleaseTime(const base::TimeTicks& release_time) { | 80 void BackoffEntry::SetCustomReleaseTime(const base::TimeTicks& release_time) { |
| 81 exponential_backoff_release_time_ = release_time; | 81 exponential_backoff_release_time_ = release_time; |
| 82 } | 82 } |
| 83 | 83 |
| 84 bool BackoffEntry::CanDiscard() const { | 84 bool BackoffEntry::CanDiscard() const { |
| 85 if (policy_->entry_lifetime_ms == -1) | 85 if (policy_->entry_lifetime_ms == -1) |
| 86 return false; | 86 return false; |
| 87 | 87 |
| 88 base::TimeTicks now = GetTimeTicksNow(); | 88 base::TimeTicks now = GetTimeTicksNow(); |
| 89 | 89 |
| 90 int64 unused_since_ms = | 90 int64_t unused_since_ms = |
| 91 (now - exponential_backoff_release_time_).InMilliseconds(); | 91 (now - exponential_backoff_release_time_).InMilliseconds(); |
| 92 | 92 |
| 93 // Release time is further than now, we are managing it. | 93 // Release time is further than now, we are managing it. |
| 94 if (unused_since_ms < 0) | 94 if (unused_since_ms < 0) |
| 95 return false; | 95 return false; |
| 96 | 96 |
| 97 if (failure_count_ > 0) { | 97 if (failure_count_ > 0) { |
| 98 // Need to keep track of failures until maximum back-off period | 98 // Need to keep track of failures until maximum back-off period |
| 99 // has passed (since further failures can add to back-off). | 99 // has passed (since further failures can add to back-off). |
| 100 return unused_since_ms >= std::max(policy_->maximum_backoff_ms, | 100 return unused_since_ms >= std::max(policy_->maximum_backoff_ms, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 128 // Never reduce previously set release horizon, e.g. due to Retry-After | 128 // Never reduce previously set release horizon, e.g. due to Retry-After |
| 129 // header. | 129 // header. |
| 130 return std::max(GetTimeTicksNow(), exponential_backoff_release_time_); | 130 return std::max(GetTimeTicksNow(), exponential_backoff_release_time_); |
| 131 } | 131 } |
| 132 | 132 |
| 133 // The delay is calculated with this formula: | 133 // The delay is calculated with this formula: |
| 134 // delay = initial_backoff * multiply_factor^( | 134 // delay = initial_backoff * multiply_factor^( |
| 135 // effective_failure_count - 1) * Uniform(1 - jitter_factor, 1] | 135 // effective_failure_count - 1) * Uniform(1 - jitter_factor, 1] |
| 136 // Note: if the failure count is too high, |delay_ms| will become infinity | 136 // Note: if the failure count is too high, |delay_ms| will become infinity |
| 137 // after the exponential calculation, and then NaN after the jitter is | 137 // after the exponential calculation, and then NaN after the jitter is |
| 138 // accounted for. Both cases are handled by using CheckedNumeric<int64> to | 138 // accounted for. Both cases are handled by using CheckedNumeric<int64_t> to |
| 139 // perform the conversion to integers. | 139 // perform the conversion to integers. |
| 140 double delay_ms = policy_->initial_delay_ms; | 140 double delay_ms = policy_->initial_delay_ms; |
| 141 delay_ms *= pow(policy_->multiply_factor, effective_failure_count - 1); | 141 delay_ms *= pow(policy_->multiply_factor, effective_failure_count - 1); |
| 142 delay_ms -= base::RandDouble() * policy_->jitter_factor * delay_ms; | 142 delay_ms -= base::RandDouble() * policy_->jitter_factor * delay_ms; |
| 143 | 143 |
| 144 // Do overflow checking in microseconds, the internal unit of TimeTicks. | 144 // Do overflow checking in microseconds, the internal unit of TimeTicks. |
| 145 base::internal::CheckedNumeric<int64> backoff_duration_us = delay_ms + 0.5; | 145 base::internal::CheckedNumeric<int64_t> backoff_duration_us = delay_ms + 0.5; |
| 146 backoff_duration_us *= base::Time::kMicrosecondsPerMillisecond; | 146 backoff_duration_us *= base::Time::kMicrosecondsPerMillisecond; |
| 147 base::TimeDelta backoff_duration = base::TimeDelta::FromMicroseconds( | 147 base::TimeDelta backoff_duration = base::TimeDelta::FromMicroseconds( |
| 148 backoff_duration_us.ValueOrDefault(kint64max)); | 148 backoff_duration_us.ValueOrDefault(kint64max)); |
| 149 base::TimeTicks release_time = BackoffDurationToReleaseTime(backoff_duration); | 149 base::TimeTicks release_time = BackoffDurationToReleaseTime(backoff_duration); |
| 150 | 150 |
| 151 // Never reduce previously set release horizon, e.g. due to Retry-After | 151 // Never reduce previously set release horizon, e.g. due to Retry-After |
| 152 // header. | 152 // header. |
| 153 return std::max(release_time, exponential_backoff_release_time_); | 153 return std::max(release_time, exponential_backoff_release_time_); |
| 154 } | 154 } |
| 155 | 155 |
| 156 base::TimeTicks BackoffEntry::BackoffDurationToReleaseTime( | 156 base::TimeTicks BackoffEntry::BackoffDurationToReleaseTime( |
| 157 base::TimeDelta backoff_duration) const { | 157 base::TimeDelta backoff_duration) const { |
| 158 const int64 kTimeTicksNowUs = | 158 const int64_t kTimeTicksNowUs = |
| 159 (GetTimeTicksNow() - base::TimeTicks()).InMicroseconds(); | 159 (GetTimeTicksNow() - base::TimeTicks()).InMicroseconds(); |
| 160 // Do overflow checking in microseconds, the internal unit of TimeTicks. | 160 // Do overflow checking in microseconds, the internal unit of TimeTicks. |
| 161 base::internal::CheckedNumeric<int64> calculated_release_time_us = | 161 base::internal::CheckedNumeric<int64_t> calculated_release_time_us = |
| 162 backoff_duration.InMicroseconds(); | 162 backoff_duration.InMicroseconds(); |
| 163 calculated_release_time_us += kTimeTicksNowUs; | 163 calculated_release_time_us += kTimeTicksNowUs; |
| 164 | 164 |
| 165 base::internal::CheckedNumeric<int64> maximum_release_time_us = kint64max; | 165 base::internal::CheckedNumeric<int64_t> maximum_release_time_us = kint64max; |
| 166 if (policy_->maximum_backoff_ms >= 0) { | 166 if (policy_->maximum_backoff_ms >= 0) { |
| 167 maximum_release_time_us = policy_->maximum_backoff_ms; | 167 maximum_release_time_us = policy_->maximum_backoff_ms; |
| 168 maximum_release_time_us *= base::Time::kMicrosecondsPerMillisecond; | 168 maximum_release_time_us *= base::Time::kMicrosecondsPerMillisecond; |
| 169 maximum_release_time_us += kTimeTicksNowUs; | 169 maximum_release_time_us += kTimeTicksNowUs; |
| 170 } | 170 } |
| 171 | 171 |
| 172 // Decide between maximum release time and calculated release time, accounting | 172 // Decide between maximum release time and calculated release time, accounting |
| 173 // for overflow with both. | 173 // for overflow with both. |
| 174 int64 release_time_us = std::min( | 174 int64_t release_time_us = |
| 175 calculated_release_time_us.ValueOrDefault(kint64max), | 175 std::min(calculated_release_time_us.ValueOrDefault(kint64max), |
| 176 maximum_release_time_us.ValueOrDefault(kint64max)); | 176 maximum_release_time_us.ValueOrDefault(kint64max)); |
| 177 | 177 |
| 178 return base::TimeTicks() + base::TimeDelta::FromMicroseconds(release_time_us); | 178 return base::TimeTicks() + base::TimeDelta::FromMicroseconds(release_time_us); |
| 179 } | 179 } |
| 180 | 180 |
| 181 base::TimeTicks BackoffEntry::GetTimeTicksNow() const { | 181 base::TimeTicks BackoffEntry::GetTimeTicksNow() const { |
| 182 return clock_ ? clock_->NowTicks() : base::TimeTicks::Now(); | 182 return clock_ ? clock_->NowTicks() : base::TimeTicks::Now(); |
| 183 } | 183 } |
| 184 | 184 |
| 185 } // namespace net | 185 } // namespace net |
| OLD | NEW |