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

Side by Side Diff: net/udp/udp_socket_win.cc

Issue 861963002: UDP: Windows implementation using non-blocking IO (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: WSAEventSelect Created 5 years, 11 months 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/udp/udp_socket_win.h" 5 #include "net/udp/udp_socket_win.h"
6 6
7 #include <mstcpip.h> 7 #include <mstcpip.h>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 public: 46 public:
47 explicit Core(UDPSocketWin* socket); 47 explicit Core(UDPSocketWin* socket);
48 48
49 // Start watching for the end of a read or write operation. 49 // Start watching for the end of a read or write operation.
50 void WatchForRead(); 50 void WatchForRead();
51 void WatchForWrite(); 51 void WatchForWrite();
52 52
53 // The UDPSocketWin is going away. 53 // The UDPSocketWin is going away.
54 void Detach() { socket_ = NULL; } 54 void Detach() { socket_ = NULL; }
55 55
56 // The separate OVERLAPPED variables for asynchronous operation. 56 // Separate events for non-blocking IO operations.
57 OVERLAPPED read_overlapped_; 57 WSAEVENT read_event_;
58 OVERLAPPED write_overlapped_; 58 WSAEVENT write_event_;
59 59
60 // The buffers used in Read() and Write(). 60 // The buffers used in Read() and Write().
61 scoped_refptr<IOBuffer> read_iobuffer_; 61 scoped_refptr<IOBuffer> read_iobuffer_;
62 scoped_refptr<IOBuffer> write_iobuffer_; 62 scoped_refptr<IOBuffer> write_iobuffer_;
63 int read_iobuffer_len_;
rvargas (doing something else) 2015/01/21 22:10:09 We are not supposed to have public variables. We s
Alpha Left Google 2015/01/22 01:01:25 Done.
64 int write_iobuffer_len_;
65 bool non_blocking_reads_initialized_;
66 bool non_blocking_writes_initialized_;
63 67
64 // The address storage passed to WSARecvFrom(). 68 // The address storage passed to WSARecvFrom().
65 SockaddrStorage recv_addr_storage_; 69 SockaddrStorage recv_addr_storage_;
66 70
67 private: 71 private:
68 friend class base::RefCounted<Core>; 72 friend class base::RefCounted<Core>;
69 73
70 class ReadDelegate : public base::win::ObjectWatcher::Delegate { 74 class ReadDelegate : public base::win::ObjectWatcher::Delegate {
71 public: 75 public:
72 explicit ReadDelegate(Core* core) : core_(core) {} 76 explicit ReadDelegate(Core* core) : core_(core) {}
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 base::win::ObjectWatcher read_watcher_; 109 base::win::ObjectWatcher read_watcher_;
106 // |write_watcher_| watches for events from Write(); 110 // |write_watcher_| watches for events from Write();
107 base::win::ObjectWatcher write_watcher_; 111 base::win::ObjectWatcher write_watcher_;
108 112
109 DISALLOW_COPY_AND_ASSIGN(Core); 113 DISALLOW_COPY_AND_ASSIGN(Core);
110 }; 114 };
111 115
112 UDPSocketWin::Core::Core(UDPSocketWin* socket) 116 UDPSocketWin::Core::Core(UDPSocketWin* socket)
113 : socket_(socket), 117 : socket_(socket),
114 reader_(this), 118 reader_(this),
115 writer_(this) { 119 writer_(this),
116 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); 120 read_iobuffer_len_(0),
117 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); 121 write_iobuffer_len_(0),
118 122 non_blocking_reads_initialized_(false),
119 read_overlapped_.hEvent = WSACreateEvent(); 123 non_blocking_writes_initialized_(false) {
120 write_overlapped_.hEvent = WSACreateEvent(); 124 read_event_ = WSACreateEvent();
125 write_event_ = WSACreateEvent();
121 } 126 }
122 127
123 UDPSocketWin::Core::~Core() { 128 UDPSocketWin::Core::~Core() {
124 // Make sure the message loop is not watching this object anymore. 129 // Make sure the message loop is not watching this object anymore.
125 read_watcher_.StopWatching(); 130 read_watcher_.StopWatching();
126 write_watcher_.StopWatching(); 131 write_watcher_.StopWatching();
127 132
128 WSACloseEvent(read_overlapped_.hEvent); 133 WSACloseEvent(read_event_);
129 memset(&read_overlapped_, 0xaf, sizeof(read_overlapped_)); 134 WSACloseEvent(write_event_);
130 WSACloseEvent(write_overlapped_.hEvent);
131 memset(&write_overlapped_, 0xaf, sizeof(write_overlapped_));
132 } 135 }
133 136
134 void UDPSocketWin::Core::WatchForRead() { 137 void UDPSocketWin::Core::WatchForRead() {
135 // We grab an extra reference because there is an IO operation in progress. 138 // We grab an extra reference because there is an IO operation in progress.
136 // Balanced in ReadDelegate::OnObjectSignaled(). 139 // Balanced in ReadDelegate::OnObjectSignaled().
137 AddRef(); 140 AddRef();
138 read_watcher_.StartWatching(read_overlapped_.hEvent, &reader_); 141 read_watcher_.StartWatching(read_event_, &reader_);
139 } 142 }
140 143
141 void UDPSocketWin::Core::WatchForWrite() { 144 void UDPSocketWin::Core::WatchForWrite() {
142 // We grab an extra reference because there is an IO operation in progress. 145 // We grab an extra reference because there is an IO operation in progress.
143 // Balanced in WriteDelegate::OnObjectSignaled(). 146 // Balanced in WriteDelegate::OnObjectSignaled().
144 AddRef(); 147 AddRef();
145 write_watcher_.StartWatching(write_overlapped_.hEvent, &writer_); 148 write_watcher_.StartWatching(write_event_, &writer_);
146 } 149 }
147 150
148 void UDPSocketWin::Core::ReadDelegate::OnObjectSignaled(HANDLE object) { 151 void UDPSocketWin::Core::ReadDelegate::OnObjectSignaled(HANDLE object) {
149 // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. 152 // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed.
150 tracked_objects::ScopedTracker tracking_profile( 153 tracked_objects::ScopedTracker tracking_profile(
151 FROM_HERE_WITH_EXPLICIT_FUNCTION( 154 FROM_HERE_WITH_EXPLICIT_FUNCTION(
152 "UDPSocketWin_Core_ReadDelegate_OnObjectSignaled")); 155 "UDPSocketWin_Core_ReadDelegate_OnObjectSignaled"));
153 156
154 DCHECK_EQ(object, core_->read_overlapped_.hEvent); 157 DCHECK_EQ(object, core_->read_event_);
155 if (core_->socket_) 158 if (core_->socket_)
156 core_->socket_->DidCompleteRead(); 159 core_->socket_->DidCompleteRead();
157 160
158 core_->Release(); 161 core_->Release();
159 } 162 }
160 163
161 void UDPSocketWin::Core::WriteDelegate::OnObjectSignaled(HANDLE object) { 164 void UDPSocketWin::Core::WriteDelegate::OnObjectSignaled(HANDLE object) {
162 // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. 165 // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed.
163 tracked_objects::ScopedTracker tracking_profile( 166 tracked_objects::ScopedTracker tracking_profile(
164 FROM_HERE_WITH_EXPLICIT_FUNCTION( 167 FROM_HERE_WITH_EXPLICIT_FUNCTION(
165 "UDPSocketWin_Core_WriteDelegate_OnObjectSignaled")); 168 "UDPSocketWin_Core_WriteDelegate_OnObjectSignaled"));
166 169
167 DCHECK_EQ(object, core_->write_overlapped_.hEvent); 170 DCHECK_EQ(object, core_->write_event_);
168 if (core_->socket_) 171 if (core_->socket_)
169 core_->socket_->DidCompleteWrite(); 172 core_->socket_->DidCompleteWrite();
170 173
171 core_->Release(); 174 core_->Release();
172 } 175 }
173 //----------------------------------------------------------------------------- 176 //-----------------------------------------------------------------------------
174 177
175 QwaveAPI::QwaveAPI() : qwave_supported_(false) { 178 QwaveAPI::QwaveAPI() : qwave_supported_(false) {
176 HMODULE qwave = LoadLibrary(L"qwave.dll"); 179 HMODULE qwave = LoadLibrary(L"qwave.dll");
177 if (!qwave) 180 if (!qwave)
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 DCHECK_NE(rv, ERR_IO_PENDING); 563 DCHECK_NE(rv, ERR_IO_PENDING);
561 DCHECK(!write_callback_.is_null()); 564 DCHECK(!write_callback_.is_null());
562 565
563 // since Run may result in Write being called, clear write_callback_ up front. 566 // since Run may result in Write being called, clear write_callback_ up front.
564 CompletionCallback c = write_callback_; 567 CompletionCallback c = write_callback_;
565 write_callback_.Reset(); 568 write_callback_.Reset();
566 c.Run(rv); 569 c.Run(rv);
567 } 570 }
568 571
569 void UDPSocketWin::DidCompleteRead() { 572 void UDPSocketWin::DidCompleteRead() {
570 DWORD num_bytes, flags; 573 WSANETWORKEVENTS network_events;
571 BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_, 574 int os_error = 0;
572 &num_bytes, FALSE, &flags); 575 int rv = WSAEnumNetworkEvents(socket_, core_->read_event_, &network_events);
573 WSAResetEvent(core_->read_overlapped_.hEvent); 576 if (rv == SOCKET_ERROR) {
574 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); 577 os_error = WSAGetLastError();
575 // Convert address. 578 rv = MapSystemError(os_error);
576 if (recv_from_address_ && result >= 0) { 579 DoReadCallback(rv);
580 return;
581 } else if (network_events.lNetworkEvents) {
Ryan Hamilton 2015/01/21 04:03:35 nit: since there was a return in the previous bloc
Alpha Left Google 2015/01/22 01:01:25 Done.
582 DCHECK(network_events.lNetworkEvents & FD_READ);
583 // If network_events.iErrorCode[FD_READ_BIT] is nonzero, still call
584 // InternalRecvFrom() because it reports a more accurate error code.
585 rv = InternalRecvFrom(core_->read_iobuffer_.get(),
586 core_->read_iobuffer_len_, recv_from_address_);
587 if (rv == ERR_IO_PENDING)
588 return;
589 } else {
590 core_->WatchForRead();
Ryan Hamilton 2015/01/21 04:03:35 Out of curiosity, what conditions lead to this bra
Alpha Left Google 2015/01/22 01:01:26 This comes from tcp_socket_win.cc. The comment th
591 return;
592 }
593 // Convert address if there's data received.
594 if (recv_from_address_ && rv >= 0) {
577 if (!ReceiveAddressToIPEndpoint(recv_from_address_)) 595 if (!ReceiveAddressToIPEndpoint(recv_from_address_))
578 result = ERR_ADDRESS_INVALID; 596 rv = ERR_ADDRESS_INVALID;
579 } 597 }
580 LogRead(result, core_->read_iobuffer_->data()); 598 LogRead(rv, core_->read_iobuffer_->data());
581 core_->read_iobuffer_ = NULL; 599 core_->read_iobuffer_ = NULL;
600 core_->read_iobuffer_len_ = 0;
582 recv_from_address_ = NULL; 601 recv_from_address_ = NULL;
583 DoReadCallback(result); 602 DoReadCallback(rv);
584 } 603 }
585 604
586 void UDPSocketWin::LogRead(int result, const char* bytes) const { 605 void UDPSocketWin::LogRead(int result, const char* bytes) const {
587 if (result < 0) { 606 if (result < 0) {
588 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result); 607 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result);
589 return; 608 return;
590 } 609 }
591 610
592 if (net_log_.IsLogging()) { 611 if (net_log_.IsLogging()) {
593 // Get address for logging, if |address| is NULL. 612 // Get address for logging, if |address| is NULL.
594 IPEndPoint address; 613 IPEndPoint address;
595 bool is_address_valid = ReceiveAddressToIPEndpoint(&address); 614 bool is_address_valid = ReceiveAddressToIPEndpoint(&address);
596 net_log_.AddEvent( 615 net_log_.AddEvent(
597 NetLog::TYPE_UDP_BYTES_RECEIVED, 616 NetLog::TYPE_UDP_BYTES_RECEIVED,
598 CreateNetLogUDPDataTranferCallback( 617 CreateNetLogUDPDataTranferCallback(
599 result, bytes, 618 result, bytes,
600 is_address_valid ? &address : NULL)); 619 is_address_valid ? &address : NULL));
601 } 620 }
602 621
603 base::StatsCounter read_bytes("udp.read_bytes"); 622 base::StatsCounter read_bytes("udp.read_bytes");
604 read_bytes.Add(result); 623 read_bytes.Add(result);
605 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(result); 624 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(result);
606 } 625 }
607 626
608 void UDPSocketWin::DidCompleteWrite() { 627 void UDPSocketWin::DidCompleteWrite() {
609 DWORD num_bytes, flags; 628 WSANETWORKEVENTS network_events;
610 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, 629 int os_error = 0;
611 &num_bytes, FALSE, &flags); 630 int rv = WSAEnumNetworkEvents(socket_, core_->write_event_, &network_events);
612 WSAResetEvent(core_->write_overlapped_.hEvent); 631 if (rv == SOCKET_ERROR) {
613 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); 632 os_error = WSAGetLastError();
614 LogWrite(result, core_->write_iobuffer_->data(), send_to_address_.get()); 633 rv = MapSystemError(os_error);
615 634 DoWriteCallback(rv);
635 return;
636 } else if (network_events.lNetworkEvents) {
637 DCHECK(network_events.lNetworkEvents & FD_WRITE);
638 // If network_events.iErrorCode[FD_WRITE_BIT] is nonzero, still call
639 // InternalSendto() because it reports a more accurate error code.
640 rv = InternalSendTo(core_->write_iobuffer_.get(),
641 core_->write_iobuffer_len_, send_to_address_.get());
642 if (rv == ERR_IO_PENDING)
643 return;
644 } else {
645 core_->WatchForWrite();
646 return;
647 }
648 LogWrite(rv, core_->write_iobuffer_->data(), send_to_address_.get());
649 core_->write_iobuffer_ = NULL;
650 core_->write_iobuffer_len_ = 0;
616 send_to_address_.reset(); 651 send_to_address_.reset();
617 core_->write_iobuffer_ = NULL; 652 DoWriteCallback(rv);
618 DoWriteCallback(result);
619 } 653 }
620 654
621 void UDPSocketWin::LogWrite(int result, 655 void UDPSocketWin::LogWrite(int result,
622 const char* bytes, 656 const char* bytes,
623 const IPEndPoint* address) const { 657 const IPEndPoint* address) const {
624 if (result < 0) { 658 if (result < 0) {
625 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result); 659 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result);
626 return; 660 return;
627 } 661 }
628 662
629 if (net_log_.IsLogging()) { 663 if (net_log_.IsLogging()) {
630 net_log_.AddEvent( 664 net_log_.AddEvent(
631 NetLog::TYPE_UDP_BYTES_SENT, 665 NetLog::TYPE_UDP_BYTES_SENT,
632 CreateNetLogUDPDataTranferCallback(result, bytes, address)); 666 CreateNetLogUDPDataTranferCallback(result, bytes, address));
633 } 667 }
634 668
635 base::StatsCounter write_bytes("udp.write_bytes"); 669 base::StatsCounter write_bytes("udp.write_bytes");
636 write_bytes.Add(result); 670 write_bytes.Add(result);
637 NetworkActivityMonitor::GetInstance()->IncrementBytesSent(result); 671 NetworkActivityMonitor::GetInstance()->IncrementBytesSent(result);
638 } 672 }
639 673
640 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len, 674 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len,
641 IPEndPoint* address) { 675 IPEndPoint* address) {
642 DCHECK(!core_->read_iobuffer_.get()); 676 if (!core_->non_blocking_reads_initialized_) {
677 // After this call we'll receive FD_READ signals when asynchronous read
rvargas (doing something else) 2015/01/21 22:10:09 nit: after this call the event will be signaled
Alpha Left Google 2015/01/22 01:01:25 Done.
678 // is completed.
679 WSAEventSelect(socket_, core_->read_event_, FD_READ);
680 core_->non_blocking_reads_initialized_ = true;
681 }
643 SockaddrStorage& storage = core_->recv_addr_storage_; 682 SockaddrStorage& storage = core_->recv_addr_storage_;
644 storage.addr_len = sizeof(storage.addr_storage); 683 storage.addr_len = sizeof(storage.addr_storage);
645 684
646 WSABUF read_buffer; 685 WSABUF read_buffer;
647 read_buffer.buf = buf->data(); 686 read_buffer.buf = buf->data();
648 read_buffer.len = buf_len; 687 read_buffer.len = buf_len;
649 688
650 DWORD flags = 0; 689 DWORD flags = 0;
651 DWORD num; 690 DWORD bytes_read;
652 CHECK_NE(INVALID_SOCKET, socket_); 691 CHECK_NE(INVALID_SOCKET, socket_);
653 AssertEventNotSignaled(core_->read_overlapped_.hEvent); 692 int rv = WSARecvFrom(socket_, &read_buffer, 1, &bytes_read, &flags,
rvargas (doing something else) 2015/01/21 22:10:09 Looks like there's no reason to use WSARecvFrom ov
Alpha Left Google 2015/01/22 01:01:25 Done.
654 int rv = WSARecvFrom(socket_, &read_buffer, 1, &num, &flags, storage.addr, 693 storage.addr, &storage.addr_len, NULL, NULL);
655 &storage.addr_len, &core_->read_overlapped_, NULL); 694 if (rv == SOCKET_ERROR) {
656 if (rv == 0) { 695 int os_error = WSAGetLastError();
657 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { 696 if (os_error != WSAEWOULDBLOCK) {
658 int result = num; 697 rv = MapSystemError(os_error);
659 // Convert address. 698 LogRead(rv, NULL);
660 if (address && result >= 0) { 699 return rv;
661 if (!ReceiveAddressToIPEndpoint(address))
662 result = ERR_ADDRESS_INVALID;
663 }
664 LogRead(result, buf->data());
665 return result;
666 } 700 }
667 } else { 701 } else {
668 int os_error = WSAGetLastError(); 702 rv = bytes_read;
669 if (os_error != WSA_IO_PENDING) { 703 // Convert address.
670 int result = MapSystemError(os_error); 704 if (address && rv >= 0 && !ReceiveAddressToIPEndpoint(address)) {
671 LogRead(result, NULL); 705 rv = ERR_ADDRESS_INVALID;
672 return result;
673 } 706 }
707 LogRead(rv, buf->data());
708 return rv;
674 } 709 }
675 core_->WatchForRead(); 710 core_->WatchForRead();
676 core_->read_iobuffer_ = buf; 711 core_->read_iobuffer_ = buf;
712 core_->read_iobuffer_len_ = buf_len;
677 return ERR_IO_PENDING; 713 return ERR_IO_PENDING;
678 } 714 }
679 715
680 int UDPSocketWin::InternalSendTo(IOBuffer* buf, int buf_len, 716 int UDPSocketWin::InternalSendTo(IOBuffer* buf, int buf_len,
681 const IPEndPoint* address) { 717 const IPEndPoint* address) {
682 DCHECK(!core_->write_iobuffer_.get()); 718 if (!core_->non_blocking_writes_initialized_) {
719 // After this call we'll receive FD_WRITE signals when asynchronous write
720 // is completed.
721 WSAEventSelect(socket_, core_->write_event_, FD_WRITE);
722 core_->non_blocking_writes_initialized_ = true;
723 }
683 SockaddrStorage storage; 724 SockaddrStorage storage;
684 struct sockaddr* addr = storage.addr; 725 struct sockaddr* addr = storage.addr;
685 // Convert address. 726 // Convert address.
686 if (!address) { 727 if (!address) {
687 addr = NULL; 728 addr = NULL;
688 storage.addr_len = 0; 729 storage.addr_len = 0;
689 } else { 730 } else {
690 if (!address->ToSockAddr(addr, &storage.addr_len)) { 731 if (!address->ToSockAddr(addr, &storage.addr_len)) {
691 int result = ERR_ADDRESS_INVALID; 732 int result = ERR_ADDRESS_INVALID;
692 LogWrite(result, NULL, NULL); 733 LogWrite(result, NULL, NULL);
693 return result; 734 return result;
694 } 735 }
695 } 736 }
696 737
697 WSABUF write_buffer; 738 WSABUF write_buffer;
698 write_buffer.buf = buf->data(); 739 write_buffer.buf = buf->data();
699 write_buffer.len = buf_len; 740 write_buffer.len = buf_len;
700 741
701 DWORD flags = 0; 742 DWORD flags = 0;
702 DWORD num; 743 DWORD bytes_written;
703 AssertEventNotSignaled(core_->write_overlapped_.hEvent); 744 int rv = WSASendTo(socket_, &write_buffer, 1, &bytes_written, flags, addr,
704 int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags, 745 storage.addr_len, NULL, NULL);
705 addr, storage.addr_len, &core_->write_overlapped_, NULL); 746 if (rv == SOCKET_ERROR) {
706 if (rv == 0) { 747 int os_error = WSAGetLastError();
707 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { 748 if (os_error != WSAEWOULDBLOCK) {
708 int result = num; 749 rv = MapSystemError(os_error);
709 LogWrite(result, buf->data(), address); 750 LogWrite(rv, NULL, NULL);
710 return result; 751 return rv;
711 } 752 }
712 } else { 753 } else {
713 int os_error = WSAGetLastError(); 754 rv = bytes_written;
714 if (os_error != WSA_IO_PENDING) { 755 LogWrite(rv, buf->data(), address);
715 int result = MapSystemError(os_error); 756 return rv;
716 LogWrite(result, NULL, NULL);
717 return result;
718 }
719 } 757 }
720
721 core_->WatchForWrite(); 758 core_->WatchForWrite();
722 core_->write_iobuffer_ = buf; 759 core_->write_iobuffer_ = buf;
760 core_->write_iobuffer_len_ = buf_len;
723 return ERR_IO_PENDING; 761 return ERR_IO_PENDING;
724 } 762 }
725 763
726 int UDPSocketWin::SetMulticastOptions() { 764 int UDPSocketWin::SetMulticastOptions() {
727 if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) { 765 if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) {
728 DWORD loop = 0; 766 DWORD loop = 0;
729 int protocol_level = 767 int protocol_level =
730 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; 768 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
731 int option = 769 int option =
732 addr_family_ == AF_INET ? IP_MULTICAST_LOOP: IPV6_MULTICAST_LOOP; 770 addr_family_ == AF_INET ? IP_MULTICAST_LOOP: IPV6_MULTICAST_LOOP;
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 NULL); 1048 NULL);
1011 1049
1012 return OK; 1050 return OK;
1013 } 1051 }
1014 1052
1015 void UDPSocketWin::DetachFromThread() { 1053 void UDPSocketWin::DetachFromThread() {
1016 base::NonThreadSafe::DetachFromThread(); 1054 base::NonThreadSafe::DetachFromThread();
1017 } 1055 }
1018 1056
1019 } // namespace net 1057 } // namespace net
OLDNEW
« net/udp/udp_socket_unittest.cc ('K') | « net/udp/udp_socket_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698