OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/browser/devtools/devtools_network_realm.h" |
| 6 |
| 7 #include "base/time/time.h" |
| 8 #include "chrome/browser/devtools/devtools_network_conditions.h" |
| 9 #include "chrome/browser/devtools/devtools_network_transaction.h" |
| 10 |
| 11 namespace { |
| 12 |
| 13 int64_t kPacketSize = 1500; |
| 14 |
| 15 } // namespace |
| 16 |
| 17 DevToolsNetworkRealm::DevToolsNetworkRealm() { |
| 18 } |
| 19 |
| 20 DevToolsNetworkRealm::~DevToolsNetworkRealm() { |
| 21 DCHECK(!conditions_); |
| 22 } |
| 23 |
| 24 void DevToolsNetworkRealm::RemoveTransaction( |
| 25 DevToolsNetworkTransaction* transaction) { |
| 26 if (!conditions_ || !conditions_->IsThrottling()) |
| 27 return; |
| 28 |
| 29 UpdateThrottles(); |
| 30 throttled_transactions_.erase(std::remove(throttled_transactions_.begin(), |
| 31 throttled_transactions_.end(), transaction), |
| 32 throttled_transactions_.end()); |
| 33 ArmTimer(); |
| 34 } |
| 35 |
| 36 void DevToolsNetworkRealm::UpdateConditions( |
| 37 const scoped_refptr<DevToolsNetworkConditions> conditions) { |
| 38 if (conditions_ && conditions_->IsThrottling()) |
| 39 UpdateThrottles(); |
| 40 |
| 41 conditions_ = conditions; |
| 42 if (!conditions || !(conditions->IsThrottling() || conditions->IsOffline())) { |
| 43 timer_.Stop(); |
| 44 int64_t length = throttled_transactions_.size(); |
| 45 for (int64_t i = 0; i < length; ++i) |
| 46 throttled_transactions_[i]->FireThrottledCallback(); |
| 47 throttled_transactions_.clear(); |
| 48 } |
| 49 |
| 50 if (!conditions) |
| 51 return; |
| 52 |
| 53 if (conditions_->IsThrottling()) { |
| 54 DCHECK(conditions_->download_throughput() != 0); |
| 55 offset_ = base::TimeTicks::Now(); |
| 56 last_tick_ = 0; |
| 57 int64_t us_tick_length = |
| 58 (1000000L * kPacketSize) / conditions_->download_throughput(); |
| 59 DCHECK(us_tick_length != 0); |
| 60 if (us_tick_length == 0) |
| 61 us_tick_length = 1; |
| 62 tick_length_ = base::TimeDelta::FromMicroseconds(us_tick_length); |
| 63 ArmTimer(); |
| 64 } |
| 65 } |
| 66 |
| 67 void DevToolsNetworkRealm::UpdateThrottles() { |
| 68 int64_t last_tick = (base::TimeTicks::Now() - offset_) / tick_length_; |
| 69 int64_t ticks = last_tick - last_tick_; |
| 70 last_tick_ = last_tick; |
| 71 |
| 72 int64_t length = throttled_transactions_.size(); |
| 73 if (!length) |
| 74 return; |
| 75 |
| 76 int64_t shift = ticks % length; |
| 77 for (int64_t i = 0; i < length; ++i) { |
| 78 throttled_transactions_[i]->DecreaseThrottledByteCount( |
| 79 (ticks / length) * kPacketSize + (i < shift ? kPacketSize : 0)); |
| 80 } |
| 81 std::rotate(throttled_transactions_.begin(), |
| 82 throttled_transactions_.begin() + shift, throttled_transactions_.end()); |
| 83 } |
| 84 |
| 85 void DevToolsNetworkRealm::OnTimer() { |
| 86 UpdateThrottles(); |
| 87 |
| 88 std::vector<DevToolsNetworkTransaction*> active_transactions; |
| 89 std::vector<DevToolsNetworkTransaction*> finished_transactions; |
| 90 size_t length = throttled_transactions_.size(); |
| 91 for (size_t i = 0; i < length; ++i) { |
| 92 if (throttled_transactions_[i]->throttled_byte_count() < 0) |
| 93 finished_transactions.push_back(throttled_transactions_[i]); |
| 94 else |
| 95 active_transactions.push_back(throttled_transactions_[i]); |
| 96 } |
| 97 throttled_transactions_.swap(active_transactions); |
| 98 |
| 99 length = finished_transactions.size(); |
| 100 for (size_t i = 0; i < length; ++i) |
| 101 finished_transactions[i]->FireThrottledCallback(); |
| 102 |
| 103 ArmTimer(); |
| 104 } |
| 105 |
| 106 void DevToolsNetworkRealm::ArmTimer() { |
| 107 size_t length = throttled_transactions_.size(); |
| 108 if (!length) |
| 109 return; |
| 110 int64_t min_ticks_left = 0x10000L; |
| 111 for (size_t i = 0; i < length; ++i) { |
| 112 int64_t packets_left = (throttled_transactions_[i]->throttled_byte_count() + |
| 113 kPacketSize - 1) / kPacketSize; |
| 114 int64_t ticks_left = (i + 1) + length * (packets_left - 1); |
| 115 if (i == 0 || ticks_left < min_ticks_left) |
| 116 min_ticks_left = ticks_left; |
| 117 } |
| 118 base::TimeTicks desired_time = |
| 119 offset_ + tick_length_ * (last_tick_ + min_ticks_left); |
| 120 timer_.Start( |
| 121 FROM_HERE, |
| 122 desired_time - base::TimeTicks::Now(), |
| 123 base::Bind( |
| 124 &DevToolsNetworkRealm::OnTimer, |
| 125 base::Unretained(this))); |
| 126 } |
| 127 |
| 128 void DevToolsNetworkRealm::ThrottleTransaction( |
| 129 DevToolsNetworkTransaction* transaction) { |
| 130 UpdateThrottles(); |
| 131 throttled_transactions_.push_back(transaction); |
| 132 ArmTimer(); |
| 133 } |
OLD | NEW |