Index: chrome/browser/devtools/devtools_network_transaction.cc |
diff --git a/chrome/browser/devtools/devtools_network_transaction.cc b/chrome/browser/devtools/devtools_network_transaction.cc |
index bba196c6bc7b3920021e1c9e995cff7ae9d6a821..3d36884ae810e867917e41c6abb125b7e525e50e 100644 |
--- a/chrome/browser/devtools/devtools_network_transaction.cc |
+++ b/chrome/browser/devtools/devtools_network_transaction.cc |
@@ -17,6 +17,7 @@ DevToolsNetworkTransaction::DevToolsNetworkTransaction( |
network_transaction_(network_transaction.Pass()), |
request_(NULL), |
failed_(false), |
+ callback_type_(NONE), |
proxy_callback_(base::Bind(&DevToolsNetworkTransaction::OnCallback, |
base::Unretained(this))) { |
DCHECK(controller); |
@@ -27,15 +28,65 @@ DevToolsNetworkTransaction::~DevToolsNetworkTransaction() { |
controller_->RemoveTransaction(this); |
} |
+void DevToolsNetworkTransaction::Throttle(int result) { |
+ throttled_result_ = result; |
+ int64_t penalty = 0; |
+ if (callback_type_ == START) |
+ penalty += network_transaction_->GetTotalReceivedBytes(); |
+ if (result > 0) |
+ penalty += result; |
+ // Ensure that callback won't fire synchronously. |
+ // TODO(eustas): Improve penalty calculation. |
+ if (penalty == 0) |
+ penalty = 1; |
+ controller_->ThrottleTransaction(this, penalty); |
+} |
+ |
void DevToolsNetworkTransaction::OnCallback(int rv) { |
if (failed_) |
return; |
DCHECK(!callback_.is_null()); |
+ if (callback_type_ == START || callback_type_ == READ) { |
+ if (controller_->ShouldThrottle(request_)) { |
+ Throttle(rv); |
+ return; |
+ } |
+ } |
net::CompletionCallback callback = callback_; |
callback_.Reset(); |
+ callback_type_ = NONE; |
callback.Run(rv); |
} |
+int DevToolsNetworkTransaction::SetupCallback( |
+ net::CompletionCallback callback, |
+ int result, |
+ CallbackType callback_type) { |
+ DCHECK(callback_type_ == NONE); |
+ |
+ if (result == net::ERR_IO_PENDING) { |
+ callback_type_ = callback_type; |
+ callback_ = callback; |
+ return result; |
+ } |
+ |
+ if (!controller_->ShouldThrottle(request_)) |
+ return result; |
+ |
+ // In case of read error we can't calculate penalty. |
vsevik
2014/06/11 12:08:51
What about if (callback_type == START && result <
eustas
2014/06/11 13:18:48
Done.
|
+ if (callback_type == READ && result < 0) |
+ return result; |
+ |
+ // URLRequestJob relies on synchronous end-of-stream notification. |
+ if (callback_type == READ && result == 0) |
+ return result; |
+ |
+ callback_type_ = callback_type; |
vsevik
2014/06/11 12:08:52
Does it mean we also throttle requests of types ot
eustas
2014/06/11 13:18:48
Done.
|
+ callback_ = callback; |
+ Throttle(result); |
+ return net::ERR_IO_PENDING; |
+} |
+ |
void DevToolsNetworkTransaction::Fail() { |
DCHECK(request_); |
DCHECK(!failed_); |
@@ -46,6 +97,7 @@ void DevToolsNetworkTransaction::Fail() { |
return; |
net::CompletionCallback callback = callback_; |
callback_.Reset(); |
+ callback_type_ = NONE; |
callback.Run(net::ERR_INTERNET_DISCONNECTED); |
} |
@@ -63,9 +115,7 @@ int DevToolsNetworkTransaction::Start( |
return net::ERR_INTERNET_DISCONNECTED; |
} |
int rv = network_transaction_->Start(request, proxy_callback_, net_log); |
- if (rv == net::ERR_IO_PENDING) |
- callback_ = callback; |
- return rv; |
+ return SetupCallback(callback, rv, START); |
} |
int DevToolsNetworkTransaction::RestartIgnoringLastError( |
@@ -73,9 +123,7 @@ int DevToolsNetworkTransaction::RestartIgnoringLastError( |
if (failed_) |
return net::ERR_INTERNET_DISCONNECTED; |
int rv = network_transaction_->RestartIgnoringLastError(proxy_callback_); |
- if (rv == net::ERR_IO_PENDING) |
- callback_ = callback; |
- return rv; |
+ return SetupCallback(callback, rv, RESTART_IGNORING_LAST_ERROR); |
} |
int DevToolsNetworkTransaction::RestartWithCertificate( |
@@ -85,9 +133,7 @@ int DevToolsNetworkTransaction::RestartWithCertificate( |
return net::ERR_INTERNET_DISCONNECTED; |
int rv = network_transaction_->RestartWithCertificate( |
client_cert, proxy_callback_); |
- if (rv == net::ERR_IO_PENDING) |
- callback_ = callback; |
- return rv; |
+ return SetupCallback(callback, rv, RESTART_WITH_CERTIFICATE); |
} |
int DevToolsNetworkTransaction::RestartWithAuth( |
@@ -96,9 +142,7 @@ int DevToolsNetworkTransaction::RestartWithAuth( |
if (failed_) |
return net::ERR_INTERNET_DISCONNECTED; |
int rv = network_transaction_->RestartWithAuth(credentials, proxy_callback_); |
- if (rv == net::ERR_IO_PENDING) |
- callback_ = callback; |
- return rv; |
+ return SetupCallback(callback, rv, RESTART_WITH_AUTH); |
} |
bool DevToolsNetworkTransaction::IsReadyToRestartForAuth() { |
@@ -112,9 +156,7 @@ int DevToolsNetworkTransaction::Read( |
if (failed_) |
return net::ERR_INTERNET_DISCONNECTED; |
int rv = network_transaction_->Read(buf, buf_len, proxy_callback_); |
- if (rv == net::ERR_IO_PENDING) |
- callback_ = callback; |
- return rv; |
+ return SetupCallback(callback, rv, READ); |
} |
void DevToolsNetworkTransaction::StopCaching() { |
@@ -176,3 +218,12 @@ int DevToolsNetworkTransaction::ResumeNetworkStart() { |
return net::ERR_INTERNET_DISCONNECTED; |
return network_transaction_->ResumeNetworkStart(); |
} |
+ |
+void DevToolsNetworkTransaction::FireThrottledCallback() { |
+ DCHECK(!callback_.is_null()); |
+ DCHECK(callback_type_ == READ || callback_type_ == START); |
vsevik
2014/06/11 12:08:52
Looks like we can get here from RestartWithAuth no
eustas
2014/06/11 13:18:48
Done.
|
+ net::CompletionCallback callback = callback_; |
+ callback_.Reset(); |
+ callback_type_ = NONE; |
+ callback.Run(throttled_result_); |
+} |