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 |