| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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.h" | 5 #include "net/socket/tcp_client_socket.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> |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 TCPClientSocketLibevent::TCPClientSocketLibevent( | 123 TCPClientSocketLibevent::TCPClientSocketLibevent( |
| 124 const AddressList& addresses, | 124 const AddressList& addresses, |
| 125 net::NetLog* net_log, | 125 net::NetLog* net_log, |
| 126 const net::NetLog::Source& source) | 126 const net::NetLog::Source& source) |
| 127 : socket_(kInvalidSocket), | 127 : socket_(kInvalidSocket), |
| 128 bound_socket_(kInvalidSocket), | 128 bound_socket_(kInvalidSocket), |
| 129 addresses_(addresses), | 129 addresses_(addresses), |
| 130 current_ai_(NULL), | 130 current_ai_(NULL), |
| 131 read_watcher_(this), | 131 read_watcher_(this), |
| 132 write_watcher_(this), | 132 write_watcher_(this), |
| 133 read_callback_(NULL), | 133 old_read_callback_(NULL), |
| 134 old_write_callback_(NULL), | 134 old_write_callback_(NULL), |
| 135 next_connect_state_(CONNECT_STATE_NONE), | 135 next_connect_state_(CONNECT_STATE_NONE), |
| 136 connect_os_error_(0), | 136 connect_os_error_(0), |
| 137 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), | 137 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), |
| 138 previously_disconnected_(false), | 138 previously_disconnected_(false), |
| 139 use_tcp_fastopen_(false), | 139 use_tcp_fastopen_(false), |
| 140 tcp_fastopen_connected_(false), | 140 tcp_fastopen_connected_(false), |
| 141 num_bytes_read_(0) { | 141 num_bytes_read_(0) { |
| 142 scoped_refptr<NetLog::EventParameters> params; | 142 scoped_refptr<NetLog::EventParameters> params; |
| 143 if (source.is_valid()) | 143 if (source.is_valid()) |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 | 458 |
| 459 return true; | 459 return true; |
| 460 } | 460 } |
| 461 | 461 |
| 462 int TCPClientSocketLibevent::Read(IOBuffer* buf, | 462 int TCPClientSocketLibevent::Read(IOBuffer* buf, |
| 463 int buf_len, | 463 int buf_len, |
| 464 OldCompletionCallback* callback) { | 464 OldCompletionCallback* callback) { |
| 465 DCHECK(CalledOnValidThread()); | 465 DCHECK(CalledOnValidThread()); |
| 466 DCHECK_NE(kInvalidSocket, socket_); | 466 DCHECK_NE(kInvalidSocket, socket_); |
| 467 DCHECK(!waiting_connect()); | 467 DCHECK(!waiting_connect()); |
| 468 DCHECK(!read_callback_); | 468 DCHECK(!old_read_callback_ && read_callback_.is_null()); |
| 469 // Synchronous operation not supported | 469 // Synchronous operation not supported |
| 470 DCHECK(callback); | 470 DCHECK(callback); |
| 471 DCHECK_GT(buf_len, 0); | 471 DCHECK_GT(buf_len, 0); |
| 472 | 472 |
| 473 int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len)); | 473 int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len)); |
| 474 if (nread >= 0) { | 474 if (nread >= 0) { |
| 475 base::StatsCounter read_bytes("tcp.read_bytes"); | 475 base::StatsCounter read_bytes("tcp.read_bytes"); |
| 476 read_bytes.Add(nread); | 476 read_bytes.Add(nread); |
| 477 num_bytes_read_ += static_cast<int64>(nread); | 477 num_bytes_read_ += static_cast<int64>(nread); |
| 478 if (nread > 0) | 478 if (nread > 0) |
| 479 use_history_.set_was_used_to_convey_data(); | 479 use_history_.set_was_used_to_convey_data(); |
| 480 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, nread, | 480 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, nread, |
| 481 buf->data()); | 481 buf->data()); |
| 482 return nread; | 482 return nread; |
| 483 } | 483 } |
| 484 if (errno != EAGAIN && errno != EWOULDBLOCK) { | 484 if (errno != EAGAIN && errno != EWOULDBLOCK) { |
| 485 DVLOG(1) << "read failed, errno " << errno; | 485 DVLOG(1) << "read failed, errno " << errno; |
| 486 return MapSystemError(errno); | 486 return MapSystemError(errno); |
| 487 } | 487 } |
| 488 | 488 |
| 489 if (!MessageLoopForIO::current()->WatchFileDescriptor( | 489 if (!MessageLoopForIO::current()->WatchFileDescriptor( |
| 490 socket_, true, MessageLoopForIO::WATCH_READ, | 490 socket_, true, MessageLoopForIO::WATCH_READ, |
| 491 &read_socket_watcher_, &read_watcher_)) { | 491 &read_socket_watcher_, &read_watcher_)) { |
| 492 DVLOG(1) << "WatchFileDescriptor failed on read, errno " << errno; | 492 DVLOG(1) << "WatchFileDescriptor failed on read, errno " << errno; |
| 493 return MapSystemError(errno); | 493 return MapSystemError(errno); |
| 494 } | 494 } |
| 495 | 495 |
| 496 read_buf_ = buf; | 496 read_buf_ = buf; |
| 497 read_buf_len_ = buf_len; | 497 read_buf_len_ = buf_len; |
| 498 old_read_callback_ = callback; |
| 499 return ERR_IO_PENDING; |
| 500 } |
| 501 int TCPClientSocketLibevent::Read(IOBuffer* buf, |
| 502 int buf_len, |
| 503 const CompletionCallback& callback) { |
| 504 DCHECK(CalledOnValidThread()); |
| 505 DCHECK_NE(kInvalidSocket, socket_); |
| 506 DCHECK(!waiting_connect()); |
| 507 DCHECK(!old_read_callback_ && read_callback_.is_null()); |
| 508 // Synchronous operation not supported |
| 509 DCHECK(!callback.is_null()); |
| 510 DCHECK_GT(buf_len, 0); |
| 511 |
| 512 int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len)); |
| 513 if (nread >= 0) { |
| 514 base::StatsCounter read_bytes("tcp.read_bytes"); |
| 515 read_bytes.Add(nread); |
| 516 num_bytes_read_ += static_cast<int64>(nread); |
| 517 if (nread > 0) |
| 518 use_history_.set_was_used_to_convey_data(); |
| 519 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, nread, |
| 520 buf->data()); |
| 521 return nread; |
| 522 } |
| 523 if (errno != EAGAIN && errno != EWOULDBLOCK) { |
| 524 DVLOG(1) << "read failed, errno " << errno; |
| 525 return MapSystemError(errno); |
| 526 } |
| 527 |
| 528 if (!MessageLoopForIO::current()->WatchFileDescriptor( |
| 529 socket_, true, MessageLoopForIO::WATCH_READ, |
| 530 &read_socket_watcher_, &read_watcher_)) { |
| 531 DVLOG(1) << "WatchFileDescriptor failed on read, errno " << errno; |
| 532 return MapSystemError(errno); |
| 533 } |
| 534 |
| 535 read_buf_ = buf; |
| 536 read_buf_len_ = buf_len; |
| 498 read_callback_ = callback; | 537 read_callback_ = callback; |
| 499 return ERR_IO_PENDING; | 538 return ERR_IO_PENDING; |
| 500 } | 539 } |
| 501 | 540 |
| 502 int TCPClientSocketLibevent::Write(IOBuffer* buf, | 541 int TCPClientSocketLibevent::Write(IOBuffer* buf, |
| 503 int buf_len, | 542 int buf_len, |
| 504 OldCompletionCallback* callback) { | 543 OldCompletionCallback* callback) { |
| 505 DCHECK(CalledOnValidThread()); | 544 DCHECK(CalledOnValidThread()); |
| 506 DCHECK_NE(kInvalidSocket, socket_); | 545 DCHECK_NE(kInvalidSocket, socket_); |
| 507 DCHECK(!waiting_connect()); | 546 DCHECK(!waiting_connect()); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 reinterpret_cast<const struct sockaddr*>(&source_address), | 650 reinterpret_cast<const struct sockaddr*>(&source_address), |
| 612 sizeof(source_address)); | 651 sizeof(source_address)); |
| 613 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, | 652 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, |
| 614 make_scoped_refptr(new NetLogStringParameter( | 653 make_scoped_refptr(new NetLogStringParameter( |
| 615 "source address", | 654 "source address", |
| 616 source_address_str))); | 655 source_address_str))); |
| 617 } | 656 } |
| 618 | 657 |
| 619 void TCPClientSocketLibevent::DoReadCallback(int rv) { | 658 void TCPClientSocketLibevent::DoReadCallback(int rv) { |
| 620 DCHECK_NE(rv, ERR_IO_PENDING); | 659 DCHECK_NE(rv, ERR_IO_PENDING); |
| 621 DCHECK(read_callback_); | 660 DCHECK(old_read_callback_ || !read_callback_.is_null()); |
| 622 | 661 |
| 623 // since Run may result in Read being called, clear read_callback_ up front. | 662 // since Run may result in Read being called, clear read_callback_ up front. |
| 624 OldCompletionCallback* c = read_callback_; | 663 if (old_read_callback_) { |
| 625 read_callback_ = NULL; | 664 OldCompletionCallback* c = old_read_callback_; |
| 626 c->Run(rv); | 665 old_read_callback_ = NULL; |
| 666 c->Run(rv); |
| 667 } else { |
| 668 CompletionCallback c = read_callback_; |
| 669 read_callback_.Reset(); |
| 670 c.Run(rv); |
| 671 } |
| 627 } | 672 } |
| 628 | 673 |
| 629 void TCPClientSocketLibevent::DoWriteCallback(int rv) { | 674 void TCPClientSocketLibevent::DoWriteCallback(int rv) { |
| 630 DCHECK_NE(rv, ERR_IO_PENDING); | 675 DCHECK_NE(rv, ERR_IO_PENDING); |
| 631 DCHECK(old_write_callback_ || !write_callback_.is_null()); | 676 DCHECK(old_write_callback_ || !write_callback_.is_null()); |
| 632 | 677 |
| 633 // since Run may result in Write being called, clear write_callback_ up front. | 678 // since Run may result in Write being called, clear write_callback_ up front. |
| 634 if (old_write_callback_) { | 679 if (old_write_callback_) { |
| 635 OldCompletionCallback* c = old_write_callback_; | 680 OldCompletionCallback* c = old_write_callback_; |
| 636 old_write_callback_ = NULL; | 681 old_write_callback_ = NULL; |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 | 812 |
| 768 int64 TCPClientSocketLibevent::NumBytesRead() const { | 813 int64 TCPClientSocketLibevent::NumBytesRead() const { |
| 769 return num_bytes_read_; | 814 return num_bytes_read_; |
| 770 } | 815 } |
| 771 | 816 |
| 772 base::TimeDelta TCPClientSocketLibevent::GetConnectTimeMicros() const { | 817 base::TimeDelta TCPClientSocketLibevent::GetConnectTimeMicros() const { |
| 773 return connect_time_micros_; | 818 return connect_time_micros_; |
| 774 } | 819 } |
| 775 | 820 |
| 776 } // namespace net | 821 } // namespace net |
| OLD | NEW |