Index: net/base/backoff_entry.cc |
diff --git a/net/base/backoff_entry.cc b/net/base/backoff_entry.cc |
index 8b1abf9b99b5f04e7bea1fa8530726f7fa4412a5..8df0641ac78fa81ee3631ea303881a9bd02d6078 100644 |
--- a/net/base/backoff_entry.cc |
+++ b/net/base/backoff_entry.cc |
@@ -12,6 +12,7 @@ |
#include "base/logging.h" |
#include "base/numerics/safe_math.h" |
#include "base/rand_util.h" |
+#include "base/strings/string_number_conversions.h" |
#include "base/values.h" |
namespace net { |
@@ -115,29 +116,46 @@ void BackoffEntry::Reset() { |
scoped_ptr<base::ListValue> BackoffEntry::Serialize() const { |
scoped_ptr<base::ListValue> serialized(new base::ListValue()); |
+ const int64 time_ticks_now_us = |
+ (ImplGetTimeNow() - base::TimeTicks()).InMicroseconds(); |
+ const int64 wall_clock_time_now_us = |
+ (ImplGetWallClockTimeNow() - base::Time()).InMicroseconds(); |
+ // Do overflow checking in microseconds, the internal unit of TimeTicks, Time |
+ // and TimeDelta. |
+ base::internal::CheckedNumeric<int64> time_until_release_us = |
+ (GetReleaseTime() - base::TimeTicks()).InMicroseconds(); |
+ time_until_release_us -= time_ticks_now_us; |
+ base::internal::CheckedNumeric<int64> wall_clock_release_time_us = |
+ time_until_release_us.ValueOrDefault(kint64min); |
+ wall_clock_release_time_us += wall_clock_time_now_us; |
+ serialized->AppendString(base::Int64ToString( |
+ wall_clock_release_time_us.ValueOrDefault(kint64max))); |
serialized->AppendInteger(failure_count_); |
- base::Time absolute_release_time = |
- (GetReleaseTime() - ImplGetTimeNow()) + ImplGetWallClockTimeNow(); |
- serialized->AppendDouble(absolute_release_time.ToDoubleT()); |
return serialized; |
} |
bool BackoffEntry::Deserialize(const base::ListValue& serialized) { |
if (serialized.GetSize() != 2) |
return false; |
- int failure_count; |
- if (!serialized.GetInteger(0, &failure_count)) |
+ std::string wall_clock_release_time_string; |
+ if (!serialized.GetString(0, &wall_clock_release_time_string)) |
return false; |
- double absolute_release_time_double; |
- if (!serialized.GetDouble(1, &absolute_release_time_double)) |
+ int64 wall_clock_release_time_us; |
+ if (!base::StringToInt64(wall_clock_release_time_string, |
+ &wall_clock_release_time_us)) |
return false; |
- failure_count_ = failure_count; |
- base::Time absolute_release_time = |
- base::Time::FromDoubleT(absolute_release_time_double); |
- base::TimeDelta time_until_release = |
- absolute_release_time - ImplGetWallClockTimeNow(); |
+ int failure_count; |
+ if (!serialized.GetInteger(1, &failure_count)) |
+ return false; |
+ const int64 wall_clock_time_now_us = |
+ (ImplGetWallClockTimeNow() - base::Time()).InMicroseconds(); |
+ base::internal::CheckedNumeric<int64> time_until_release_us = |
+ wall_clock_release_time_us; |
+ time_until_release_us -= wall_clock_time_now_us; |
exponential_backoff_release_time_ = |
- TimeUntilReleaseToReleaseTime(time_until_release); |
+ TimeUntilReleaseToReleaseTime(base::TimeDelta::FromMicroseconds( |
+ time_until_release_us.ValueOrDefault(kint64min))); |
+ failure_count_ = failure_count; |
return true; |
} |