| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_socket.h" | 5 #include "net/socket/tcp_socket.h" |
| 6 #include "net/socket/tcp_socket_win.h" | 6 #include "net/socket/tcp_socket_win.h" |
| 7 | 7 |
| 8 #include <mstcpip.h> | 8 #include <mstcpip.h> |
| 9 | 9 |
| 10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 return result; | 317 return result; |
| 318 } | 318 } |
| 319 | 319 |
| 320 return OK; | 320 return OK; |
| 321 } | 321 } |
| 322 | 322 |
| 323 int TCPSocketWin::AdoptConnectedSocket(SOCKET socket, | 323 int TCPSocketWin::AdoptConnectedSocket(SOCKET socket, |
| 324 const IPEndPoint& peer_address) { | 324 const IPEndPoint& peer_address) { |
| 325 DCHECK(CalledOnValidThread()); | 325 DCHECK(CalledOnValidThread()); |
| 326 DCHECK_EQ(socket_, INVALID_SOCKET); | 326 DCHECK_EQ(socket_, INVALID_SOCKET); |
| 327 DCHECK(!core_); | 327 DCHECK(!core_.get()); |
| 328 | 328 |
| 329 socket_ = socket; | 329 socket_ = socket; |
| 330 | 330 |
| 331 if (SetNonBlocking(socket_)) { | 331 if (SetNonBlocking(socket_)) { |
| 332 int result = MapSystemError(WSAGetLastError()); | 332 int result = MapSystemError(WSAGetLastError()); |
| 333 Close(); | 333 Close(); |
| 334 return result; | 334 return result; |
| 335 } | 335 } |
| 336 | 336 |
| 337 core_ = new Core(this); | 337 core_ = new Core(this); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 DCHECK(!waiting_connect_); | 429 DCHECK(!waiting_connect_); |
| 430 | 430 |
| 431 // |peer_address_| and |core_| will be non-NULL if Connect() has been called. | 431 // |peer_address_| and |core_| will be non-NULL if Connect() has been called. |
| 432 // Unless Close() is called to reset the internal state, a second call to | 432 // Unless Close() is called to reset the internal state, a second call to |
| 433 // Connect() is not allowed. | 433 // Connect() is not allowed. |
| 434 // Please note that we enforce this even if the previous Connect() has | 434 // Please note that we enforce this even if the previous Connect() has |
| 435 // completed and failed. Although it is allowed to connect the same |socket_| | 435 // completed and failed. Although it is allowed to connect the same |socket_| |
| 436 // again after a connection attempt failed on Windows, it results in | 436 // again after a connection attempt failed on Windows, it results in |
| 437 // unspecified behavior according to POSIX. Therefore, we make it behave in | 437 // unspecified behavior according to POSIX. Therefore, we make it behave in |
| 438 // the same way as TCPSocketLibevent. | 438 // the same way as TCPSocketLibevent. |
| 439 DCHECK(!peer_address_ && !core_); | 439 DCHECK(!peer_address_ && !core_.get()); |
| 440 | 440 |
| 441 if (!logging_multiple_connect_attempts_) | 441 if (!logging_multiple_connect_attempts_) |
| 442 LogConnectBegin(AddressList(address)); | 442 LogConnectBegin(AddressList(address)); |
| 443 | 443 |
| 444 peer_address_.reset(new IPEndPoint(address)); | 444 peer_address_.reset(new IPEndPoint(address)); |
| 445 | 445 |
| 446 int rv = DoConnect(); | 446 int rv = DoConnect(); |
| 447 if (rv == ERR_IO_PENDING) { | 447 if (rv == ERR_IO_PENDING) { |
| 448 // Synchronous operation not supported. | 448 // Synchronous operation not supported. |
| 449 DCHECK(!callback.is_null()); | 449 DCHECK(!callback.is_null()); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 return true; | 497 return true; |
| 498 } | 498 } |
| 499 | 499 |
| 500 int TCPSocketWin::Read(IOBuffer* buf, | 500 int TCPSocketWin::Read(IOBuffer* buf, |
| 501 int buf_len, | 501 int buf_len, |
| 502 const CompletionCallback& callback) { | 502 const CompletionCallback& callback) { |
| 503 DCHECK(CalledOnValidThread()); | 503 DCHECK(CalledOnValidThread()); |
| 504 DCHECK_NE(socket_, INVALID_SOCKET); | 504 DCHECK_NE(socket_, INVALID_SOCKET); |
| 505 DCHECK(!waiting_read_); | 505 DCHECK(!waiting_read_); |
| 506 CHECK(read_callback_.is_null()); | 506 CHECK(read_callback_.is_null()); |
| 507 DCHECK(!core_->read_iobuffer_); | 507 DCHECK(!core_->read_iobuffer_.get()); |
| 508 | 508 |
| 509 return DoRead(buf, buf_len, callback); | 509 return DoRead(buf, buf_len, callback); |
| 510 } | 510 } |
| 511 | 511 |
| 512 int TCPSocketWin::Write(IOBuffer* buf, | 512 int TCPSocketWin::Write(IOBuffer* buf, |
| 513 int buf_len, | 513 int buf_len, |
| 514 const CompletionCallback& callback) { | 514 const CompletionCallback& callback) { |
| 515 DCHECK(CalledOnValidThread()); | 515 DCHECK(CalledOnValidThread()); |
| 516 DCHECK_NE(socket_, INVALID_SOCKET); | 516 DCHECK_NE(socket_, INVALID_SOCKET); |
| 517 DCHECK(!waiting_write_); | 517 DCHECK(!waiting_write_); |
| 518 CHECK(write_callback_.is_null()); | 518 CHECK(write_callback_.is_null()); |
| 519 DCHECK_GT(buf_len, 0); | 519 DCHECK_GT(buf_len, 0); |
| 520 DCHECK(!core_->write_iobuffer_); | 520 DCHECK(!core_->write_iobuffer_.get()); |
| 521 | 521 |
| 522 base::StatsCounter writes("tcp.writes"); | 522 base::StatsCounter writes("tcp.writes"); |
| 523 writes.Increment(); | 523 writes.Increment(); |
| 524 | 524 |
| 525 WSABUF write_buffer; | 525 WSABUF write_buffer; |
| 526 write_buffer.len = buf_len; | 526 write_buffer.len = buf_len; |
| 527 write_buffer.buf = buf->data(); | 527 write_buffer.buf = buf->data(); |
| 528 | 528 |
| 529 // TODO(wtc): Remove the assertion after enough testing. | 529 // TODO(wtc): Remove the assertion after enough testing. |
| 530 AssertEventNotSignaled(core_->write_overlapped_.hEvent); | 530 AssertEventNotSignaled(core_->write_overlapped_.hEvent); |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 682 accept_socket_ = NULL; | 682 accept_socket_ = NULL; |
| 683 accept_address_ = NULL; | 683 accept_address_ = NULL; |
| 684 accept_callback_.Reset(); | 684 accept_callback_.Reset(); |
| 685 } | 685 } |
| 686 | 686 |
| 687 if (accept_event_) { | 687 if (accept_event_) { |
| 688 WSACloseEvent(accept_event_); | 688 WSACloseEvent(accept_event_); |
| 689 accept_event_ = WSA_INVALID_EVENT; | 689 accept_event_ = WSA_INVALID_EVENT; |
| 690 } | 690 } |
| 691 | 691 |
| 692 if (core_) { | 692 if (core_.get()) { |
| 693 if (waiting_connect_) { | 693 if (waiting_connect_) { |
| 694 // We closed the socket, so this notification will never come. | 694 // We closed the socket, so this notification will never come. |
| 695 // From MSDN' WSAEventSelect documentation: | 695 // From MSDN' WSAEventSelect documentation: |
| 696 // "Closing a socket with closesocket also cancels the association and | 696 // "Closing a socket with closesocket also cancels the association and |
| 697 // selection of network events specified in WSAEventSelect for the | 697 // selection of network events specified in WSAEventSelect for the |
| 698 // socket". | 698 // socket". |
| 699 core_->Release(); | 699 core_->Release(); |
| 700 } | 700 } |
| 701 core_->Detach(); | 701 core_->Detach(); |
| 702 core_ = NULL; | 702 core_ = NULL; |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 789 DCHECK(ev.lNetworkEvents == 0); | 789 DCHECK(ev.lNetworkEvents == 0); |
| 790 | 790 |
| 791 // Start watching the next FD_ACCEPT event. | 791 // Start watching the next FD_ACCEPT event. |
| 792 WSAEventSelect(socket_, accept_event_, FD_ACCEPT); | 792 WSAEventSelect(socket_, accept_event_, FD_ACCEPT); |
| 793 accept_watcher_.StartWatching(accept_event_, this); | 793 accept_watcher_.StartWatching(accept_event_, this); |
| 794 } | 794 } |
| 795 } | 795 } |
| 796 | 796 |
| 797 int TCPSocketWin::DoConnect() { | 797 int TCPSocketWin::DoConnect() { |
| 798 DCHECK_EQ(connect_os_error_, 0); | 798 DCHECK_EQ(connect_os_error_, 0); |
| 799 DCHECK(!core_); | 799 DCHECK(!core_.get()); |
| 800 | 800 |
| 801 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, | 801 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, |
| 802 CreateNetLogIPEndPointCallback(peer_address_.get())); | 802 CreateNetLogIPEndPointCallback(peer_address_.get())); |
| 803 | 803 |
| 804 core_ = new Core(this); | 804 core_ = new Core(this); |
| 805 // WSAEventSelect sets the socket to non-blocking mode as a side effect. | 805 // WSAEventSelect sets the socket to non-blocking mode as a side effect. |
| 806 // Our connect() and recv() calls require that the socket be non-blocking. | 806 // Our connect() and recv() calls require that the socket be non-blocking. |
| 807 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, FD_CONNECT); | 807 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, FD_CONNECT); |
| 808 | 808 |
| 809 SockaddrStorage storage; | 809 SockaddrStorage storage; |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1011 // WSAAsyncSelect recommend we still call DoRead(): | 1011 // WSAAsyncSelect recommend we still call DoRead(): |
| 1012 // FD_CLOSE should only be posted after all data is read from a | 1012 // FD_CLOSE should only be posted after all data is read from a |
| 1013 // socket, but an application should check for remaining data upon | 1013 // socket, but an application should check for remaining data upon |
| 1014 // receipt of FD_CLOSE to avoid any possibility of losing data. | 1014 // receipt of FD_CLOSE to avoid any possibility of losing data. |
| 1015 // | 1015 // |
| 1016 // If network_events.iErrorCode[FD_READ_BIT] or | 1016 // If network_events.iErrorCode[FD_READ_BIT] or |
| 1017 // network_events.iErrorCode[FD_CLOSE_BIT] is nonzero, still call | 1017 // network_events.iErrorCode[FD_CLOSE_BIT] is nonzero, still call |
| 1018 // DoRead() because recv() reports a more accurate error code | 1018 // DoRead() because recv() reports a more accurate error code |
| 1019 // (WSAECONNRESET vs. WSAECONNABORTED) when the connection was | 1019 // (WSAECONNRESET vs. WSAECONNABORTED) when the connection was |
| 1020 // reset. | 1020 // reset. |
| 1021 rv = DoRead(core_->read_iobuffer_, core_->read_buffer_length_, | 1021 rv = DoRead(core_->read_iobuffer_.get(), core_->read_buffer_length_, |
| 1022 read_callback_); | 1022 read_callback_); |
| 1023 if (rv == ERR_IO_PENDING) | 1023 if (rv == ERR_IO_PENDING) |
| 1024 return; | 1024 return; |
| 1025 } else { | 1025 } else { |
| 1026 // This may happen because Read() may succeed synchronously and | 1026 // This may happen because Read() may succeed synchronously and |
| 1027 // consume all the received data without resetting the event object. | 1027 // consume all the received data without resetting the event object. |
| 1028 core_->WatchForRead(); | 1028 core_->WatchForRead(); |
| 1029 return; | 1029 return; |
| 1030 } | 1030 } |
| 1031 | 1031 |
| 1032 waiting_read_ = false; | 1032 waiting_read_ = false; |
| 1033 core_->read_iobuffer_ = NULL; | 1033 core_->read_iobuffer_ = NULL; |
| 1034 core_->read_buffer_length_ = 0; | 1034 core_->read_buffer_length_ = 0; |
| 1035 | 1035 |
| 1036 DCHECK_NE(rv, ERR_IO_PENDING); | 1036 DCHECK_NE(rv, ERR_IO_PENDING); |
| 1037 // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. | 1037 // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. |
| 1038 tracked_objects::ScopedTracker tracking_profile( | 1038 tracked_objects::ScopedTracker tracking_profile( |
| 1039 FROM_HERE_WITH_EXPLICIT_FUNCTION("TCPSocketWin::DidSignalRead")); | 1039 FROM_HERE_WITH_EXPLICIT_FUNCTION("TCPSocketWin::DidSignalRead")); |
| 1040 base::ResetAndReturn(&read_callback_).Run(rv); | 1040 base::ResetAndReturn(&read_callback_).Run(rv); |
| 1041 } | 1041 } |
| 1042 | 1042 |
| 1043 } // namespace net | 1043 } // namespace net |
| OLD | NEW |