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

Side by Side Diff: net/socket/tcp_client_socket_libevent.cc

Issue 344026: Add LoadLog to ClientSocket::Connect(). (Closed)
Patch Set: Minor build fixups and fixed mac bug. Created 11 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « net/socket/tcp_client_socket_libevent.h ('k') | net/socket/tcp_client_socket_pool.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/socket/tcp_client_socket_libevent.h" 5 #include "net/socket/tcp_client_socket_libevent.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <netdb.h> 9 #include <netdb.h>
10 #include <sys/socket.h> 10 #include <sys/socket.h>
11 11
12 #include "base/eintr_wrapper.h" 12 #include "base/eintr_wrapper.h"
13 #include "base/message_loop.h" 13 #include "base/message_loop.h"
14 #include "base/string_util.h" 14 #include "base/string_util.h"
15 #include "base/trace_event.h" 15 #include "base/trace_event.h"
16 #include "net/base/io_buffer.h" 16 #include "net/base/io_buffer.h"
17 #include "net/base/load_log.h"
17 #include "net/base/net_errors.h" 18 #include "net/base/net_errors.h"
18 #include "third_party/libevent/event.h" 19 #include "third_party/libevent/event.h"
19 20
20 21
21 namespace net { 22 namespace net {
22 23
23 namespace { 24 namespace {
24 25
25 const int kInvalidSocket = -1; 26 const int kInvalidSocket = -1;
26 27
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 read_watcher_(this), 111 read_watcher_(this),
111 write_watcher_(this), 112 write_watcher_(this),
112 read_callback_(NULL), 113 read_callback_(NULL),
113 write_callback_(NULL) { 114 write_callback_(NULL) {
114 } 115 }
115 116
116 TCPClientSocketLibevent::~TCPClientSocketLibevent() { 117 TCPClientSocketLibevent::~TCPClientSocketLibevent() {
117 Disconnect(); 118 Disconnect();
118 } 119 }
119 120
120 int TCPClientSocketLibevent::Connect(CompletionCallback* callback) { 121 int TCPClientSocketLibevent::Connect(CompletionCallback* callback,
122 LoadLog* load_log) {
121 // If already connected, then just return OK. 123 // If already connected, then just return OK.
122 if (socket_ != kInvalidSocket) 124 if (socket_ != kInvalidSocket)
123 return OK; 125 return OK;
124 126
125 DCHECK(!waiting_connect_); 127 DCHECK(!waiting_connect_);
128 DCHECK(!load_log_);
126 129
127 TRACE_EVENT_BEGIN("socket.connect", this, ""); 130 TRACE_EVENT_BEGIN("socket.connect", this, "");
128 131
132 LoadLog::BeginEvent(load_log, LoadLog::TYPE_TCP_CONNECT);
133
134 int rv = DoConnect();
135
136 if (rv == ERR_IO_PENDING) {
137 // Synchronous operation not supported.
138 DCHECK(callback);
139
140 load_log_ = load_log;
141 waiting_connect_ = true;
142 write_callback_ = callback;
143 } else {
144 TRACE_EVENT_END("socket.connect", this, "");
145 LoadLog::EndEvent(load_log, LoadLog::TYPE_TCP_CONNECT);
146 }
147
148 return rv;
149 }
150
151 int TCPClientSocketLibevent::DoConnect() {
129 while (true) { 152 while (true) {
130 DCHECK(current_ai_); 153 DCHECK(current_ai_);
131 154
132 int rv = CreateSocket(current_ai_); 155 int rv = CreateSocket(current_ai_);
133 if (rv != OK) 156 if (rv != OK)
134 return rv; 157 return rv;
135 158
136 if (!HANDLE_EINTR(connect(socket_, current_ai_->ai_addr, 159 if (!HANDLE_EINTR(connect(socket_, current_ai_->ai_addr,
137 static_cast<int>(current_ai_->ai_addrlen)))) { 160 static_cast<int>(current_ai_->ai_addrlen)))) {
138 TRACE_EVENT_END("socket.connect", this, "");
139 // Connected without waiting! 161 // Connected without waiting!
140 return OK; 162 return OK;
141 } 163 }
142 164
143 int error_code = errno; 165 int error_code = errno;
144 if (error_code == EINPROGRESS) 166 if (error_code == EINPROGRESS)
145 break; 167 break;
146 168
147 close(socket_); 169 close(socket_);
148 socket_ = kInvalidSocket; 170 socket_ = kInvalidSocket;
149 171
150 if (current_ai_->ai_next && ShouldTryNextAddress(error_code)) { 172 if (current_ai_->ai_next && ShouldTryNextAddress(error_code)) {
151 // connect() can fail synchronously for an address even on a 173 // connect() can fail synchronously for an address even on a
152 // non-blocking socket. As an example, this can happen when there is 174 // non-blocking socket. As an example, this can happen when there is
153 // no route to the host. Retry using the next address in the list. 175 // no route to the host. Retry using the next address in the list.
154 current_ai_ = current_ai_->ai_next; 176 current_ai_ = current_ai_->ai_next;
155 } else { 177 } else {
156 DLOG(INFO) << "connect failed: " << error_code; 178 DLOG(INFO) << "connect failed: " << error_code;
157 return MapConnectError(error_code); 179 return MapConnectError(error_code);
158 } 180 }
159 } 181 }
160 182
161 // Synchronous operation not supported
162 DCHECK(callback);
163
164 // Initialize write_socket_watcher_ and link it to our MessagePump. 183 // Initialize write_socket_watcher_ and link it to our MessagePump.
165 // POLLOUT is set if the connection is established. 184 // POLLOUT is set if the connection is established.
166 // POLLIN is set if the connection fails. 185 // POLLIN is set if the connection fails.
167 if (!MessageLoopForIO::current()->WatchFileDescriptor( 186 if (!MessageLoopForIO::current()->WatchFileDescriptor(
168 socket_, true, MessageLoopForIO::WATCH_WRITE, &write_socket_watcher_, 187 socket_, true, MessageLoopForIO::WATCH_WRITE, &write_socket_watcher_,
169 &write_watcher_)) { 188 &write_watcher_)) {
170 DLOG(INFO) << "WatchFileDescriptor failed: " << errno; 189 DLOG(INFO) << "WatchFileDescriptor failed: " << errno;
171 close(socket_); 190 close(socket_);
172 socket_ = kInvalidSocket; 191 socket_ = kInvalidSocket;
173 return MapPosixError(errno); 192 return MapPosixError(errno);
174 } 193 }
175 194
176 waiting_connect_ = true;
177 write_callback_ = callback;
178 return ERR_IO_PENDING; 195 return ERR_IO_PENDING;
179 } 196 }
180 197
181 void TCPClientSocketLibevent::Disconnect() { 198 void TCPClientSocketLibevent::Disconnect() {
182 if (socket_ == kInvalidSocket) 199 if (socket_ == kInvalidSocket)
183 return; 200 return;
184 201
185 TRACE_EVENT_INSTANT("socket.disconnect", this, ""); 202 TRACE_EVENT_INSTANT("socket.disconnect", this, "");
186 203
187 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); 204 bool ok = read_socket_watcher_.StopWatchingFileDescriptor();
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 355
339 // since Run may result in Write being called, clear write_callback_ up front. 356 // since Run may result in Write being called, clear write_callback_ up front.
340 CompletionCallback* c = write_callback_; 357 CompletionCallback* c = write_callback_;
341 write_callback_ = NULL; 358 write_callback_ = NULL;
342 c->Run(rv); 359 c->Run(rv);
343 } 360 }
344 361
345 void TCPClientSocketLibevent::DidCompleteConnect() { 362 void TCPClientSocketLibevent::DidCompleteConnect() {
346 int result = ERR_UNEXPECTED; 363 int result = ERR_UNEXPECTED;
347 364
348 TRACE_EVENT_END("socket.connect", this, "");
349
350 // Check to see if connect succeeded 365 // Check to see if connect succeeded
351 int error_code = 0; 366 int error_code = 0;
352 socklen_t len = sizeof(error_code); 367 socklen_t len = sizeof(error_code);
353 if (getsockopt(socket_, SOL_SOCKET, SO_ERROR, &error_code, &len) < 0) 368 if (getsockopt(socket_, SOL_SOCKET, SO_ERROR, &error_code, &len) < 0)
354 error_code = errno; 369 error_code = errno;
355 370
356 if (error_code == EINPROGRESS || error_code == EALREADY) { 371 if (error_code == EINPROGRESS || error_code == EALREADY) {
357 NOTREACHED(); // This indicates a bug in libevent or our code. 372 NOTREACHED(); // This indicates a bug in libevent or our code.
358 result = ERR_IO_PENDING; 373 result = ERR_IO_PENDING;
359 } else if (current_ai_->ai_next && ShouldTryNextAddress(error_code)) { 374 } else if (current_ai_->ai_next && ShouldTryNextAddress(error_code)) {
360 // This address failed, try next one in list. 375 // This address failed, try next one in list.
361 const addrinfo* next = current_ai_->ai_next; 376 const addrinfo* next = current_ai_->ai_next;
362 Disconnect(); 377 Disconnect();
363 current_ai_ = next; 378 current_ai_ = next;
364 result = Connect(write_callback_); 379 scoped_refptr<LoadLog> load_log;
380 load_log.swap(load_log_);
381 TRACE_EVENT_END("socket.connect", this, "");
382 LoadLog::EndEvent(load_log, LoadLog::TYPE_TCP_CONNECT);
383 result = Connect(write_callback_, load_log);
365 } else { 384 } else {
366 result = MapConnectError(error_code); 385 result = MapConnectError(error_code);
367 bool ok = write_socket_watcher_.StopWatchingFileDescriptor(); 386 bool ok = write_socket_watcher_.StopWatchingFileDescriptor();
368 DCHECK(ok); 387 DCHECK(ok);
369 waiting_connect_ = false; 388 waiting_connect_ = false;
389 TRACE_EVENT_END("socket.connect", this, "");
390 LoadLog::EndEvent(load_log_, LoadLog::TYPE_TCP_CONNECT);
391 load_log_ = NULL;
370 } 392 }
371 393
372 if (result != ERR_IO_PENDING) { 394 if (result != ERR_IO_PENDING) {
373 DoWriteCallback(result); 395 DoWriteCallback(result);
374 } 396 }
375 } 397 }
376 398
377 void TCPClientSocketLibevent::DidCompleteRead() { 399 void TCPClientSocketLibevent::DidCompleteRead() {
378 int bytes_transferred; 400 int bytes_transferred;
379 bytes_transferred = HANDLE_EINTR(read(socket_, read_buf_->data(), 401 bytes_transferred = HANDLE_EINTR(read(socket_, read_buf_->data(),
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 DoWriteCallback(result); 440 DoWriteCallback(result);
419 } 441 }
420 } 442 }
421 443
422 int TCPClientSocketLibevent::GetPeerName(struct sockaddr *name, 444 int TCPClientSocketLibevent::GetPeerName(struct sockaddr *name,
423 socklen_t *namelen) { 445 socklen_t *namelen) {
424 return ::getpeername(socket_, name, namelen); 446 return ::getpeername(socket_, name, namelen);
425 } 447 }
426 448
427 } // namespace net 449 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/tcp_client_socket_libevent.h ('k') | net/socket/tcp_client_socket_pool.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698