| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/memory_debug.h" | 9 #include "base/memory_debug.h" |
| 10 #include "base/stats_counters.h" | 10 #include "base/stats_counters.h" |
| 11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 12 #include "base/sys_info.h" | 12 #include "base/sys_info.h" |
| 13 #include "net/base/address_list_net_log_param.h" | 13 #include "net/base/address_list_net_log_param.h" |
| 14 #include "net/base/connection_type_histograms.h" | 14 #include "net/base/connection_type_histograms.h" |
| 15 #include "net/base/io_buffer.h" | 15 #include "net/base/io_buffer.h" |
| 16 #include "net/base/net_errors.h" | 16 #include "net/base/net_errors.h" |
| 17 #include "net/base/net_log.h" | 17 #include "net/base/net_log.h" |
| 18 #include "net/base/net_util.h" | 18 #include "net/base/net_util.h" |
| 19 #include "net/base/sys_addrinfo.h" | 19 #include "net/base/sys_addrinfo.h" |
| 20 #include "net/base/winsock_init.h" | 20 #include "net/base/winsock_init.h" |
| 21 | 21 |
| 22 namespace net { | 22 namespace net { |
| 23 | 23 |
| 24 namespace { | 24 namespace { |
| 25 | 25 |
| 26 // Assert that the (manual-reset) event object is not signaled. |
| 27 void AssertEventNotSignaled(WSAEVENT hEvent) { |
| 28 DWORD wait_rv = WaitForSingleObject(hEvent, 0); |
| 29 if (wait_rv != WAIT_TIMEOUT) { |
| 30 DWORD err = ERROR_SUCCESS; |
| 31 if (wait_rv == WAIT_FAILED) |
| 32 err = GetLastError(); |
| 33 CHECK(false); // Crash. |
| 34 // This LOG statement is unreachable since we have already crashed, but it |
| 35 // should prevent the compiler from optimizing away the |wait_rv| and |
| 36 // |err| variables so they appear nicely on the stack in crash dumps. |
| 37 LOG(INFO) << "wait_rv=" << wait_rv << ", err=" << err; |
| 38 } |
| 39 } |
| 40 |
| 26 // If the (manual-reset) event object is signaled, resets it and returns true. | 41 // If the (manual-reset) event object is signaled, resets it and returns true. |
| 27 // Otherwise, does nothing and returns false. Called after a Winsock function | 42 // Otherwise, does nothing and returns false. Called after a Winsock function |
| 28 // succeeds synchronously | 43 // succeeds synchronously |
| 29 // | 44 // |
| 30 // Our testing shows that except in rare cases (when running inside QEMU), | 45 // Our testing shows that except in rare cases (when running inside QEMU), |
| 31 // the event object is already signaled at this point, so we call this method | 46 // the event object is already signaled at this point, so we call this method |
| 32 // to avoid a context switch in common cases. This is just a performance | 47 // to avoid a context switch in common cases. This is just a performance |
| 33 // optimization. The code still works if this function simply returns false. | 48 // optimization. The code still works if this function simply returns false. |
| 34 bool ResetEventIfSignaled(WSAEVENT hEvent) { | 49 bool ResetEventIfSignaled(WSAEVENT hEvent) { |
| 35 // TODO(wtc): Remove the CHECKs after enough testing. | 50 // TODO(wtc): Remove the CHECKs after enough testing. |
| (...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 501 DCHECK_NE(socket_, INVALID_SOCKET); | 516 DCHECK_NE(socket_, INVALID_SOCKET); |
| 502 DCHECK(!waiting_read_); | 517 DCHECK(!waiting_read_); |
| 503 DCHECK(!read_callback_); | 518 DCHECK(!read_callback_); |
| 504 DCHECK(!core_->read_iobuffer_); | 519 DCHECK(!core_->read_iobuffer_); |
| 505 | 520 |
| 506 buf_len = core_->ThrottleReadSize(buf_len); | 521 buf_len = core_->ThrottleReadSize(buf_len); |
| 507 | 522 |
| 508 core_->read_buffer_.len = buf_len; | 523 core_->read_buffer_.len = buf_len; |
| 509 core_->read_buffer_.buf = buf->data(); | 524 core_->read_buffer_.buf = buf->data(); |
| 510 | 525 |
| 511 // TODO(wtc): Remove the CHECK after enough testing. | 526 // TODO(wtc): Remove the assertion after enough testing. |
| 512 CHECK_EQ(static_cast<DWORD>(WAIT_TIMEOUT), | 527 AssertEventNotSignaled(core_->read_overlapped_.hEvent); |
| 513 WaitForSingleObject(core_->read_overlapped_.hEvent, 0)); | |
| 514 DWORD num, flags = 0; | 528 DWORD num, flags = 0; |
| 515 int rv = WSARecv(socket_, &core_->read_buffer_, 1, &num, &flags, | 529 int rv = WSARecv(socket_, &core_->read_buffer_, 1, &num, &flags, |
| 516 &core_->read_overlapped_, NULL); | 530 &core_->read_overlapped_, NULL); |
| 517 if (rv == 0) { | 531 if (rv == 0) { |
| 518 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { | 532 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { |
| 519 // Because of how WSARecv fills memory when used asynchronously, Purify | 533 // Because of how WSARecv fills memory when used asynchronously, Purify |
| 520 // isn't able to detect that it's been initialized, so it scans for 0xcd | 534 // isn't able to detect that it's been initialized, so it scans for 0xcd |
| 521 // in the buffer and reports UMRs (uninitialized memory reads) for those | 535 // in the buffer and reports UMRs (uninitialized memory reads) for those |
| 522 // individual bytes. We override that in PURIFY builds to avoid the | 536 // individual bytes. We override that in PURIFY builds to avoid the |
| 523 // false error reports. | 537 // false error reports. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 551 DCHECK_GT(buf_len, 0); | 565 DCHECK_GT(buf_len, 0); |
| 552 DCHECK(!core_->write_iobuffer_); | 566 DCHECK(!core_->write_iobuffer_); |
| 553 | 567 |
| 554 static StatsCounter reads("tcp.writes"); | 568 static StatsCounter reads("tcp.writes"); |
| 555 reads.Increment(); | 569 reads.Increment(); |
| 556 | 570 |
| 557 core_->write_buffer_.len = buf_len; | 571 core_->write_buffer_.len = buf_len; |
| 558 core_->write_buffer_.buf = buf->data(); | 572 core_->write_buffer_.buf = buf->data(); |
| 559 core_->write_buffer_length_ = buf_len; | 573 core_->write_buffer_length_ = buf_len; |
| 560 | 574 |
| 561 // TODO(wtc): Remove the CHECK after enough testing. | 575 // TODO(wtc): Remove the assertion after enough testing. |
| 562 CHECK_EQ(static_cast<DWORD>(WAIT_TIMEOUT), | 576 AssertEventNotSignaled(core_->write_overlapped_.hEvent); |
| 563 WaitForSingleObject(core_->write_overlapped_.hEvent, 0)); | |
| 564 DWORD num; | 577 DWORD num; |
| 565 int rv = WSASend(socket_, &core_->write_buffer_, 1, &num, 0, | 578 int rv = WSASend(socket_, &core_->write_buffer_, 1, &num, 0, |
| 566 &core_->write_overlapped_, NULL); | 579 &core_->write_overlapped_, NULL); |
| 567 if (rv == 0) { | 580 if (rv == 0) { |
| 568 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { | 581 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { |
| 569 rv = static_cast<int>(num); | 582 rv = static_cast<int>(num); |
| 570 if (rv > buf_len || rv < 0) { | 583 if (rv > buf_len || rv < 0) { |
| 571 // It seems that some winsock interceptors report that more was written | 584 // It seems that some winsock interceptors report that more was written |
| 572 // than was available. Treat this as an error. http://crbug.com/27870 | 585 // than was available. Treat this as an error. http://crbug.com/27870 |
| 573 LOG(ERROR) << "Detected broken LSP: Asked to write " << buf_len | 586 LOG(ERROR) << "Detected broken LSP: Asked to write " << buf_len |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 768 } else { | 781 } else { |
| 769 net_log_.AddEvent(NetLog::TYPE_SOCKET_BYTES_SENT, | 782 net_log_.AddEvent(NetLog::TYPE_SOCKET_BYTES_SENT, |
| 770 new NetLogIntegerParameter("num_bytes", rv)); | 783 new NetLogIntegerParameter("num_bytes", rv)); |
| 771 } | 784 } |
| 772 } | 785 } |
| 773 core_->write_iobuffer_ = NULL; | 786 core_->write_iobuffer_ = NULL; |
| 774 DoWriteCallback(rv); | 787 DoWriteCallback(rv); |
| 775 } | 788 } |
| 776 | 789 |
| 777 } // namespace net | 790 } // namespace net |
| OLD | NEW |