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

Side by Side Diff: net/socket/tcp_client_socket_win.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_win.h ('k') | net/socket/tcp_pinger.h » ('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_win.h" 5 #include "net/socket/tcp_client_socket_win.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/field_trial.h" // for SlowStart trial 9 #include "base/field_trial.h" // for SlowStart trial
10 #include "base/memory_debug.h" 10 #include "base/memory_debug.h"
11 #include "base/stats_counters.h" 11 #include "base/stats_counters.h"
12 #include "base/string_util.h" 12 #include "base/string_util.h"
13 #include "base/sys_info.h" 13 #include "base/sys_info.h"
14 #include "base/trace_event.h" 14 #include "base/trace_event.h"
15 #include "net/base/io_buffer.h" 15 #include "net/base/io_buffer.h"
16 #include "net/base/load_log.h"
16 #include "net/base/net_errors.h" 17 #include "net/base/net_errors.h"
17 #include "net/base/winsock_init.h" 18 #include "net/base/winsock_init.h"
18 19
19 namespace net { 20 namespace net {
20 21
21 namespace { 22 namespace {
22 23
23 // If the (manual-reset) event object is signaled, resets it and returns true. 24 // If the (manual-reset) event object is signaled, resets it and returns true.
24 // Otherwise, does nothing and returns false. Called after a Winsock function 25 // Otherwise, does nothing and returns false. Called after a Winsock function
25 // succeeds synchronously 26 // succeeds synchronously
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 waiting_write_(false), 265 waiting_write_(false),
265 read_callback_(NULL), 266 read_callback_(NULL),
266 write_callback_(NULL) { 267 write_callback_(NULL) {
267 EnsureWinsockInit(); 268 EnsureWinsockInit();
268 } 269 }
269 270
270 TCPClientSocketWin::~TCPClientSocketWin() { 271 TCPClientSocketWin::~TCPClientSocketWin() {
271 Disconnect(); 272 Disconnect();
272 } 273 }
273 274
274 int TCPClientSocketWin::Connect(CompletionCallback* callback) { 275 int TCPClientSocketWin::Connect(CompletionCallback* callback,
276 LoadLog* load_log) {
275 // If already connected, then just return OK. 277 // If already connected, then just return OK.
276 if (socket_ != INVALID_SOCKET) 278 if (socket_ != INVALID_SOCKET)
277 return OK; 279 return OK;
278 280
281 DCHECK(!load_log_);
282
279 static StatsCounter connects("tcp.connect"); 283 static StatsCounter connects("tcp.connect");
280 connects.Increment(); 284 connects.Increment();
281 285
282 TRACE_EVENT_BEGIN("socket.connect", this, ""); 286 TRACE_EVENT_BEGIN("socket.connect", this, "");
287
288 LoadLog::BeginEvent(load_log, LoadLog::TYPE_TCP_CONNECT);
289
290 int rv = DoConnect();
291
292 if (rv == ERR_IO_PENDING) {
293 // Synchronous operation not supported.
294 DCHECK(callback);
295
296 load_log_ = load_log;
297 waiting_connect_ = true;
298 read_callback_ = callback;
299 } else {
300 TRACE_EVENT_END("socket.connect", this, "");
301 LoadLog::EndEvent(load_log, LoadLog::TYPE_TCP_CONNECT);
302 }
303
304 return rv;
305 }
306
307 int TCPClientSocketWin::DoConnect() {
283 const struct addrinfo* ai = current_ai_; 308 const struct addrinfo* ai = current_ai_;
284 DCHECK(ai); 309 DCHECK(ai);
285 310
286 int rv = CreateSocket(ai); 311 int rv = CreateSocket(ai);
287 if (rv != OK) 312 if (rv != OK)
288 return rv; 313 return rv;
289 314
290 DCHECK(!core_); 315 DCHECK(!core_);
291 core_ = new Core(this); 316 core_ = new Core(this);
292 317
(...skipping 11 matching lines...) Expand all
304 // The MSDN page for connect says: 329 // The MSDN page for connect says:
305 // With a nonblocking socket, the connection attempt cannot be completed 330 // With a nonblocking socket, the connection attempt cannot be completed
306 // immediately. In this case, connect will return SOCKET_ERROR, and 331 // immediately. In this case, connect will return SOCKET_ERROR, and
307 // WSAGetLastError will return WSAEWOULDBLOCK. 332 // WSAGetLastError will return WSAEWOULDBLOCK.
308 // which implies that for a nonblocking socket, connect never returns 0. 333 // which implies that for a nonblocking socket, connect never returns 0.
309 // It's not documented whether the event object will be signaled or not 334 // It's not documented whether the event object will be signaled or not
310 // if connect does return 0. So the code below is essentially dead code 335 // if connect does return 0. So the code below is essentially dead code
311 // and we don't know if it's correct. 336 // and we don't know if it's correct.
312 NOTREACHED(); 337 NOTREACHED();
313 338
314 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { 339 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent))
315 TRACE_EVENT_END("socket.connect", this, "");
316 return OK; 340 return OK;
317 }
318 } else { 341 } else {
319 DWORD err = WSAGetLastError(); 342 DWORD err = WSAGetLastError();
320 if (err != WSAEWOULDBLOCK) { 343 if (err != WSAEWOULDBLOCK) {
321 LOG(ERROR) << "connect failed: " << err; 344 LOG(ERROR) << "connect failed: " << err;
322 return MapConnectError(err); 345 return MapConnectError(err);
323 } 346 }
324 } 347 }
325 348
326 core_->WatchForRead(); 349 core_->WatchForRead();
327 waiting_connect_ = true;
328 read_callback_ = callback;
329 return ERR_IO_PENDING; 350 return ERR_IO_PENDING;
330 } 351 }
331 352
332 void TCPClientSocketWin::Disconnect() { 353 void TCPClientSocketWin::Disconnect() {
333 if (socket_ == INVALID_SOCKET) 354 if (socket_ == INVALID_SOCKET)
334 return; 355 return;
335 356
336 TRACE_EVENT_INSTANT("socket.disconnect", this, ""); 357 TRACE_EVENT_INSTANT("socket.disconnect", this, "");
337 358
338 // Note: don't use CancelIo to cancel pending IO because it doesn't work 359 // Note: don't use CancelIo to cancel pending IO because it doesn't work
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 // since Run may result in Write being called, clear write_callback_ up front. 601 // since Run may result in Write being called, clear write_callback_ up front.
581 CompletionCallback* c = write_callback_; 602 CompletionCallback* c = write_callback_;
582 write_callback_ = NULL; 603 write_callback_ = NULL;
583 c->Run(rv); 604 c->Run(rv);
584 } 605 }
585 606
586 void TCPClientSocketWin::DidCompleteConnect() { 607 void TCPClientSocketWin::DidCompleteConnect() {
587 DCHECK(waiting_connect_); 608 DCHECK(waiting_connect_);
588 int result; 609 int result;
589 610
590 TRACE_EVENT_END("socket.connect", this, "");
591 waiting_connect_ = false; 611 waiting_connect_ = false;
592 612
593 WSANETWORKEVENTS events; 613 WSANETWORKEVENTS events;
594 int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, 614 int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent,
595 &events); 615 &events);
596 if (rv == SOCKET_ERROR) { 616 if (rv == SOCKET_ERROR) {
597 NOTREACHED(); 617 NOTREACHED();
598 result = MapWinsockError(WSAGetLastError()); 618 result = MapWinsockError(WSAGetLastError());
599 } else if (events.lNetworkEvents & FD_CONNECT) { 619 } else if (events.lNetworkEvents & FD_CONNECT) {
600 DWORD error_code = static_cast<DWORD>(events.iErrorCode[FD_CONNECT_BIT]); 620 DWORD error_code = static_cast<DWORD>(events.iErrorCode[FD_CONNECT_BIT]);
601 if (current_ai_->ai_next && ( 621 if (current_ai_->ai_next && (
602 error_code == WSAEADDRNOTAVAIL || 622 error_code == WSAEADDRNOTAVAIL ||
603 error_code == WSAEAFNOSUPPORT || 623 error_code == WSAEAFNOSUPPORT ||
604 error_code == WSAECONNREFUSED || 624 error_code == WSAECONNREFUSED ||
605 error_code == WSAENETUNREACH || 625 error_code == WSAENETUNREACH ||
606 error_code == WSAEHOSTUNREACH || 626 error_code == WSAEHOSTUNREACH ||
607 error_code == WSAETIMEDOUT)) { 627 error_code == WSAETIMEDOUT)) {
608 // Try using the next address. 628 // Try using the next address.
609 const struct addrinfo* next = current_ai_->ai_next; 629 const struct addrinfo* next = current_ai_->ai_next;
610 Disconnect(); 630 Disconnect();
611 current_ai_ = next; 631 current_ai_ = next;
612 result = Connect(read_callback_); 632 scoped_refptr<LoadLog> load_log;
633 load_log.swap(load_log_);
634 TRACE_EVENT_END("socket.connect", this, "");
635 LoadLog::EndEvent(load_log, LoadLog::TYPE_TCP_CONNECT);
636 result = Connect(read_callback_, load_log);
613 } else { 637 } else {
614 result = MapConnectError(error_code); 638 result = MapConnectError(error_code);
639 TRACE_EVENT_END("socket.connect", this, "");
640 LoadLog::EndEvent(load_log_, LoadLog::TYPE_TCP_CONNECT);
641 load_log_ = NULL;
615 } 642 }
616 } else { 643 } else {
617 NOTREACHED(); 644 NOTREACHED();
618 result = ERR_UNEXPECTED; 645 result = ERR_UNEXPECTED;
646 TRACE_EVENT_END("socket.connect", this, "");
647 LoadLog::EndEvent(load_log_, LoadLog::TYPE_TCP_CONNECT);
648 load_log_ = NULL;
619 } 649 }
620 650
621 if (result != ERR_IO_PENDING) 651 if (result != ERR_IO_PENDING)
622 DoReadCallback(result); 652 DoReadCallback(result);
623 } 653 }
624 654
625 void TCPClientSocketWin::DidCompleteRead() { 655 void TCPClientSocketWin::DidCompleteRead() {
626 DCHECK(waiting_read_); 656 DCHECK(waiting_read_);
627 DWORD num_bytes, flags; 657 DWORD num_bytes, flags;
628 BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_, 658 BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_,
(...skipping 12 matching lines...) Expand all
641 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, 671 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_,
642 &num_bytes, FALSE, &flags); 672 &num_bytes, FALSE, &flags);
643 WSAResetEvent(core_->write_overlapped_.hEvent); 673 WSAResetEvent(core_->write_overlapped_.hEvent);
644 TRACE_EVENT_END("socket.write", this, StringPrintf("%d bytes", num_bytes)); 674 TRACE_EVENT_END("socket.write", this, StringPrintf("%d bytes", num_bytes));
645 waiting_write_ = false; 675 waiting_write_ = false;
646 core_->write_iobuffer_ = NULL; 676 core_->write_iobuffer_ = NULL;
647 DoWriteCallback(ok ? num_bytes : MapWinsockError(WSAGetLastError())); 677 DoWriteCallback(ok ? num_bytes : MapWinsockError(WSAGetLastError()));
648 } 678 }
649 679
650 } // namespace net 680 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/tcp_client_socket_win.h ('k') | net/socket/tcp_pinger.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698