summaryrefslogtreecommitdiffstats
path: root/net/socket/tcp_client_socket_pool.cc
diff options
context:
space:
mode:
Diffstat (limited to 'net/socket/tcp_client_socket_pool.cc')
-rw-r--r--net/socket/tcp_client_socket_pool.cc93
1 files changed, 60 insertions, 33 deletions
diff --git a/net/socket/tcp_client_socket_pool.cc b/net/socket/tcp_client_socket_pool.cc
index c9af808..a5b5595 100644
--- a/net/socket/tcp_client_socket_pool.cc
+++ b/net/socket/tcp_client_socket_pool.cc
@@ -25,14 +25,12 @@ TCPConnectJob::TCPConnectJob(
ClientSocketFactory* client_socket_factory,
HostResolver* host_resolver,
Delegate* delegate)
- : group_name_(group_name),
+ : ConnectJob(group_name, handle, delegate),
resolve_info_(resolve_info),
- handle_(handle),
client_socket_factory_(client_socket_factory),
ALLOW_THIS_IN_INITIALIZER_LIST(
callback_(this,
&TCPConnectJob::OnIOComplete)),
- delegate_(delegate),
resolver_(host_resolver) {}
TCPConnectJob::~TCPConnectJob() {
@@ -41,33 +39,73 @@ TCPConnectJob::~TCPConnectJob() {
}
int TCPConnectJob::Connect() {
- set_load_state(LOAD_STATE_RESOLVING_HOST);
- int rv = resolver_.Resolve(resolve_info_, &addresses_, &callback_);
+ next_state_ = kStateResolveHost;
+ return DoLoop(OK);
+}
+
+void TCPConnectJob::OnIOComplete(int result) {
+ int rv = DoLoop(result);
if (rv != ERR_IO_PENDING)
- rv = OnIOCompleteInternal(rv, true /* synchronous */);
+ delegate()->OnConnectJobComplete(rv, this); // Deletes |this|
+}
+
+int TCPConnectJob::DoLoop(int result) {
+ DCHECK_NE(next_state_, kStateNone);
+
+ int rv = result;
+ do {
+ State state = next_state_;
+ next_state_ = kStateNone;
+ switch (state) {
+ case kStateResolveHost:
+ DCHECK_EQ(OK, rv);
+ rv = DoResolveHost();
+ break;
+ case kStateResolveHostComplete:
+ rv = DoResolveHostComplete(rv);
+ break;
+ case kStateTCPConnect:
+ DCHECK_EQ(OK, rv);
+ rv = DoTCPConnect();
+ break;
+ case kStateTCPConnectComplete:
+ rv = DoTCPConnectComplete(rv);
+ break;
+ default:
+ NOTREACHED();
+ rv = ERR_FAILED;
+ break;
+ }
+ } while (rv != ERR_IO_PENDING && next_state_ != kStateNone);
+
return rv;
}
-void TCPConnectJob::OnIOComplete(int result) {
- OnIOCompleteInternal(result, false /* asynchronous */);
+int TCPConnectJob::DoResolveHost() {
+ set_load_state(LOAD_STATE_RESOLVING_HOST);
+ next_state_ = kStateResolveHostComplete;
+ return resolver_.Resolve(resolve_info_, &addresses_, &callback_);
}
-int TCPConnectJob::OnIOCompleteInternal(
- int result, bool synchronous) {
- CHECK(result != ERR_IO_PENDING);
-
- if (result == OK && load_state() == LOAD_STATE_RESOLVING_HOST) {
- set_load_state(LOAD_STATE_CONNECTING);
- socket_.reset(client_socket_factory_->CreateTCPClientSocket(addresses_));
- connect_start_time_ = base::TimeTicks::Now();
- result = socket_->Connect(&callback_);
- if (result == ERR_IO_PENDING)
- return result;
- }
+int TCPConnectJob::DoResolveHostComplete(int result) {
+ DCHECK_EQ(LOAD_STATE_RESOLVING_HOST, load_state());
+ if (result == OK)
+ next_state_ = kStateTCPConnect;
+ return result;
+}
+int TCPConnectJob::DoTCPConnect() {
+ next_state_ = kStateTCPConnectComplete;
+ set_load_state(LOAD_STATE_CONNECTING);
+ set_socket(client_socket_factory_->CreateTCPClientSocket(addresses_));
+ connect_start_time_ = base::TimeTicks::Now();
+ return socket()->Connect(&callback_);
+}
+
+int TCPConnectJob::DoTCPConnectComplete(int result) {
+ DCHECK_EQ(load_state(), LOAD_STATE_CONNECTING);
if (result == OK) {
- DCHECK_EQ(load_state(), LOAD_STATE_CONNECTING);
- CHECK(connect_start_time_ != base::TimeTicks());
+ DCHECK(connect_start_time_ != base::TimeTicks());
base::TimeDelta connect_duration =
base::TimeTicks::Now() - connect_start_time_;
@@ -78,17 +116,6 @@ int TCPConnectJob::OnIOCompleteInternal(
100);
}
- // Now, we either succeeded at Connect()'ing, or we failed at host resolution
- // or Connect()'ing. Either way, we'll run the callback to alert the client.
-
- delegate_->OnConnectJobComplete(
- group_name_,
- handle_,
- result == OK ? socket_.release() : NULL,
- result,
- !synchronous);
-
- // |this| is deleted after this point.
return result;
}