Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1810)

Unified Diff: chrome/browser/extensions/api/cast_channel/cast_socket.cc

Issue 393023003: Added connection timeout functionality to CastSocket. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: JS API plumbing, switch approach from MessageLoop to Timer, better testing. Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/api/cast_channel/cast_socket.cc
diff --git a/chrome/browser/extensions/api/cast_channel/cast_socket.cc b/chrome/browser/extensions/api/cast_channel/cast_socket.cc
index 6130d92e18755dc825880177b785f7536baf5afc..fda2186193ef6d1aefce1d124d7d41d98dfd6ade 100644
--- a/chrome/browser/extensions/api/cast_channel/cast_socket.cc
+++ b/chrome/browser/extensions/api/cast_channel/cast_socket.cc
@@ -67,7 +67,8 @@ CastSocket::CastSocket(const std::string& owner_extension_id,
const net::IPEndPoint& ip_endpoint,
ChannelAuthType channel_auth,
CastSocket::Delegate* delegate,
- net::NetLog* net_log) :
+ net::NetLog* net_log,
+ int timeout_ms) :
ApiResource(owner_extension_id),
channel_id_(0),
ip_endpoint_(ip_endpoint),
@@ -80,7 +81,9 @@ CastSocket::CastSocket(const std::string& owner_extension_id,
write_state_(WRITE_STATE_NONE),
read_state_(READ_STATE_NONE),
error_state_(CHANNEL_ERROR_NONE),
- ready_state_(READY_STATE_NONE) {
+ ready_state_(READY_STATE_NONE),
+ timeout_interval_ms_(timeout_ms),
+ connect_timeout_timer_(new base::OneShotTimer<CastSocket>) {
DCHECK(net_log_);
DCHECK(channel_auth_ == CHANNEL_AUTH_TYPE_SSL ||
channel_auth_ == CHANNEL_AUTH_TYPE_SSL_VERIFIED);
@@ -171,16 +174,32 @@ void CastSocket::Connect(const net::CompletionCallback& callback) {
ready_state_ = READY_STATE_CONNECTING;
connect_callback_ = callback;
connect_state_ = CONN_STATE_TCP_CONNECT;
+ if (timeout_interval_ms_ > 0) {
+ connect_timeout_timer_->Start(
+ FROM_HERE,
+ base::TimeDelta::FromMilliseconds(timeout_interval_ms_),
+ base::Bind(&CastSocket::CancelConnect, AsWeakPtr()));
+ }
DoConnectLoop(net::OK);
}
void CastSocket::PostTaskToStartConnectLoop(int result) {
DCHECK(CalledOnValidThread());
- base::MessageLoop::current()->PostTask(
+ task_tracker_.PostTask(
+ base::MessageLoop::current()->task_runner(),
FROM_HERE,
base::Bind(&CastSocket::DoConnectLoop, AsWeakPtr(), result));
}
+void CastSocket::CancelConnect() {
+ DCHECK(CalledOnValidThread());
+ // Stop all pending connection setup tasks and report back to the client.
+ VLOG(1) << "Timeout while establishing a connection.";
+ task_tracker_.TryCancelAll();
+ CloseWithError(CHANNEL_ERROR_CONNECT_TIMEOUT);
+ DoConnectCallback(net::ERR_TIMED_OUT);
+}
+
// This method performs the state machine transitions for connection flow.
// There are two entry points to this method:
// 1. Connect method: this starts the flow
@@ -229,8 +248,10 @@ void CastSocket::DoConnectLoop(int result) {
// b. The Do* method called did not change state
// Connect loop is finished: if there is no pending IO invoke the callback.
- if (rv != net::ERR_IO_PENDING)
+ if (rv != net::ERR_IO_PENDING) {
+ connect_timeout_timer_->Stop();
DoConnectCallback(rv);
+ }
}
int CastSocket::DoTcpConnect() {
@@ -282,7 +303,8 @@ int CastSocket::DoAuthChallengeSend() {
// Post a task to send auth challenge so that DoWriteLoop is not nested inside
// DoConnectLoop. This is not strictly necessary but keeps the write loop
// code decoupled from connect loop code.
- base::MessageLoop::current()->PostTask(
+ task_tracker_.PostTask(
+ base::MessageLoop::current()->task_runner(),
FROM_HERE,
base::Bind(&CastSocket::SendCastMessageInternal, AsWeakPtr(),
challenge_message,
@@ -316,8 +338,13 @@ int CastSocket::DoAuthChallengeReplyComplete(int result) {
void CastSocket::DoConnectCallback(int result) {
ready_state_ = (result == net::OK) ? READY_STATE_OPEN : READY_STATE_CLOSED;
- error_state_ = (result == net::OK) ?
- CHANNEL_ERROR_NONE : CHANNEL_ERROR_CONNECT_ERROR;
+ if (result == net::OK) {
+ error_state_ = CHANNEL_ERROR_NONE;
+ } else if (result == net::ERR_TIMED_OUT) {
+ error_state_ = CHANNEL_ERROR_CONNECT_TIMEOUT;
+ } else {
+ error_state_ = CHANNEL_ERROR_CONNECT_ERROR;
+ }
if (result == net::OK) // Start the read loop
PostTaskToStartReadLoop();
base::ResetAndReturn(&connect_callback_).Run(result);
@@ -496,7 +523,8 @@ int CastSocket::DoWriteError(int result) {
void CastSocket::PostTaskToStartReadLoop() {
DCHECK(CalledOnValidThread());
- base::MessageLoop::current()->PostTask(
+ task_tracker_.PostTask(
+ base::MessageLoop::current()->task_runner(),
FROM_HERE,
base::Bind(&CastSocket::StartReadLoop, AsWeakPtr()));
}
@@ -682,7 +710,7 @@ bool CastSocket::Serialize(const CastMessage& message_proto,
header.SetMessageSize(message_size);
header.PrependToString(message_data);
return true;
-};
+}
void CastSocket::CloseWithError(ChannelError error) {
DCHECK(CalledOnValidThread());
@@ -702,6 +730,10 @@ bool CastSocket::CalledOnValidThread() const {
return thread_checker_.CalledOnValidThread();
}
+void CastSocket::InjectTimerForTesting(scoped_ptr<base::Timer> injected_timer) {
+ connect_timeout_timer_ = injected_timer.Pass();
+}
+
CastSocket::MessageHeader::MessageHeader() : message_size(0) { }
void CastSocket::MessageHeader::SetMessageSize(size_t size) {

Powered by Google App Engine
This is Rietveld 408576698