Add signalSyncPoint to the WebGraphicsContext3D command buffer impls.
[chromium-blink-merge.git] / net / socket / client_socket_handle.cc
blobb6b11990cc32a1d26eedf536cd9206b527c86104
1 // Copyright (c) 2012 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.
5 #include "net/socket/client_socket_handle.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/compiler_specific.h"
10 #include "base/metrics/histogram.h"
11 #include "base/logging.h"
12 #include "net/base/net_errors.h"
13 #include "net/socket/client_socket_pool.h"
14 #include "net/socket/client_socket_pool_histograms.h"
16 namespace net {
18 ClientSocketHandle::ClientSocketHandle()
19 : is_initialized_(false),
20 pool_(NULL),
21 layered_pool_(NULL),
22 is_reused_(false),
23 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
24 base::Bind(&ClientSocketHandle::OnIOComplete,
25 base::Unretained(this)))),
26 is_ssl_error_(false) {}
28 ClientSocketHandle::~ClientSocketHandle() {
29 Reset();
32 void ClientSocketHandle::Reset() {
33 ResetInternal(true);
34 ResetErrorState();
37 void ClientSocketHandle::ResetInternal(bool cancel) {
38 if (group_name_.empty()) // Was Init called?
39 return;
40 if (is_initialized()) {
41 // Because of http://crbug.com/37810 we may not have a pool, but have
42 // just a raw socket.
43 socket_->NetLog().EndEvent(NetLog::TYPE_SOCKET_IN_USE);
44 if (pool_)
45 // If we've still got a socket, release it back to the ClientSocketPool so
46 // it can be deleted or reused.
47 pool_->ReleaseSocket(group_name_, release_socket(), pool_id_);
48 } else if (cancel) {
49 // If we did not get initialized yet, we've got a socket request pending.
50 // Cancel it.
51 pool_->CancelRequest(group_name_, this);
53 is_initialized_ = false;
54 group_name_.clear();
55 is_reused_ = false;
56 user_callback_.Reset();
57 if (layered_pool_) {
58 pool_->RemoveLayeredPool(layered_pool_);
59 layered_pool_ = NULL;
61 pool_ = NULL;
62 idle_time_ = base::TimeDelta();
63 init_time_ = base::TimeTicks();
64 setup_time_ = base::TimeDelta();
65 connect_timing_ = LoadTimingInfo::ConnectTiming();
66 pool_id_ = -1;
69 void ClientSocketHandle::ResetErrorState() {
70 is_ssl_error_ = false;
71 ssl_error_response_info_ = HttpResponseInfo();
72 pending_http_proxy_connection_.reset();
75 LoadState ClientSocketHandle::GetLoadState() const {
76 CHECK(!is_initialized());
77 CHECK(!group_name_.empty());
78 // Because of http://crbug.com/37810 we may not have a pool, but have
79 // just a raw socket.
80 if (!pool_)
81 return LOAD_STATE_IDLE;
82 return pool_->GetLoadState(group_name_, this);
85 bool ClientSocketHandle::IsPoolStalled() const {
86 return pool_->IsStalled();
89 void ClientSocketHandle::AddLayeredPool(LayeredPool* layered_pool) {
90 CHECK(layered_pool);
91 CHECK(!layered_pool_);
92 if (pool_) {
93 pool_->AddLayeredPool(layered_pool);
94 layered_pool_ = layered_pool;
98 void ClientSocketHandle::RemoveLayeredPool(LayeredPool* layered_pool) {
99 CHECK(layered_pool);
100 CHECK(layered_pool_);
101 if (pool_) {
102 pool_->RemoveLayeredPool(layered_pool);
103 layered_pool_ = NULL;
107 bool ClientSocketHandle::GetLoadTimingInfo(
108 bool is_reused,
109 LoadTimingInfo* load_timing_info) const {
110 // Only return load timing information when there's a socket.
111 if (!socket_)
112 return false;
114 load_timing_info->socket_log_id = socket_->NetLog().source().id;
115 load_timing_info->socket_reused = is_reused;
117 // No times if the socket is reused.
118 if (is_reused)
119 return true;
121 load_timing_info->connect_timing = connect_timing_;
122 return true;
125 void ClientSocketHandle::OnIOComplete(int result) {
126 CompletionCallback callback = user_callback_;
127 user_callback_.Reset();
128 HandleInitCompletion(result);
129 callback.Run(result);
132 void ClientSocketHandle::HandleInitCompletion(int result) {
133 CHECK_NE(ERR_IO_PENDING, result);
134 ClientSocketPoolHistograms* histograms = pool_->histograms();
135 histograms->AddErrorCode(result);
136 if (result != OK) {
137 if (!socket_.get())
138 ResetInternal(false); // Nothing to cancel since the request failed.
139 else
140 is_initialized_ = true;
141 return;
143 is_initialized_ = true;
144 CHECK_NE(-1, pool_id_) << "Pool should have set |pool_id_| to a valid value.";
145 setup_time_ = base::TimeTicks::Now() - init_time_;
147 histograms->AddSocketType(reuse_type());
148 switch (reuse_type()) {
149 case ClientSocketHandle::UNUSED:
150 histograms->AddRequestTime(setup_time());
151 break;
152 case ClientSocketHandle::UNUSED_IDLE:
153 histograms->AddUnusedIdleTime(idle_time());
154 break;
155 case ClientSocketHandle::REUSED_IDLE:
156 histograms->AddReusedIdleTime(idle_time());
157 break;
158 default:
159 NOTREACHED();
160 break;
163 // Broadcast that the socket has been acquired.
164 // TODO(eroman): This logging is not complete, in particular set_socket() and
165 // release() socket. It ends up working though, since those methods are being
166 // used to layer sockets (and the destination sources are the same).
167 DCHECK(socket_.get());
168 socket_->NetLog().BeginEvent(
169 NetLog::TYPE_SOCKET_IN_USE,
170 requesting_source_.ToEventParametersCallback());
173 } // namespace net