OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "media/cast/net/udp_transport.h" | 5 #include "media/cast/net/udp_transport.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
60 bytes_sent_(0), | 60 bytes_sent_(0), |
61 weak_factory_(this) { | 61 weak_factory_(this) { |
62 DCHECK(!IsEmpty(local_end_point) || !IsEmpty(remote_end_point)); | 62 DCHECK(!IsEmpty(local_end_point) || !IsEmpty(remote_end_point)); |
63 } | 63 } |
64 | 64 |
65 UdpTransport::~UdpTransport() {} | 65 UdpTransport::~UdpTransport() {} |
66 | 66 |
67 void UdpTransport::StartReceiving( | 67 void UdpTransport::StartReceiving( |
68 const PacketReceiverCallbackWithStatus& packet_receiver) { | 68 const PacketReceiverCallbackWithStatus& packet_receiver) { |
69 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); | 69 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); |
70 | 70 |
miu
2015/05/08 06:49:05
Should there be a guard here too?
if (!udp_sock
hubbe
2015/05/18 20:41:06
Done.
Although, a DCHECK might be better as we do
| |
71 packet_receiver_ = packet_receiver; | 71 packet_receiver_ = packet_receiver; |
72 udp_socket_->SetMulticastLoopbackMode(true); | 72 udp_socket_->SetMulticastLoopbackMode(true); |
73 if (!IsEmpty(local_addr_)) { | 73 if (!IsEmpty(local_addr_)) { |
74 if (udp_socket_->Open(local_addr_.GetFamily()) < 0 || | 74 if (udp_socket_->Open(local_addr_.GetFamily()) < 0 || |
75 udp_socket_->AllowAddressReuse() < 0 || | 75 udp_socket_->AllowAddressReuse() < 0 || |
76 udp_socket_->Bind(local_addr_) < 0) { | 76 udp_socket_->Bind(local_addr_) < 0) { |
77 udp_socket_->Close(); | 77 udp_socket_->Close(); |
78 udp_socket_.reset(); | |
78 status_callback_.Run(TRANSPORT_SOCKET_ERROR); | 79 status_callback_.Run(TRANSPORT_SOCKET_ERROR); |
79 LOG(ERROR) << "Failed to bind local address."; | 80 LOG(ERROR) << "Failed to bind local address."; |
80 return; | 81 return; |
81 } | 82 } |
82 } else if (!IsEmpty(remote_addr_)) { | 83 } else if (!IsEmpty(remote_addr_)) { |
83 if (udp_socket_->Open(remote_addr_.GetFamily()) < 0 || | 84 if (udp_socket_->Open(remote_addr_.GetFamily()) < 0 || |
84 udp_socket_->AllowAddressReuse() < 0 || | 85 udp_socket_->AllowAddressReuse() < 0 || |
85 udp_socket_->Connect(remote_addr_) < 0) { | 86 udp_socket_->Connect(remote_addr_) < 0) { |
86 udp_socket_->Close(); | 87 udp_socket_->Close(); |
88 udp_socket_.reset(); | |
87 status_callback_.Run(TRANSPORT_SOCKET_ERROR); | 89 status_callback_.Run(TRANSPORT_SOCKET_ERROR); |
88 LOG(ERROR) << "Failed to connect to remote address."; | 90 LOG(ERROR) << "Failed to connect to remote address."; |
89 return; | 91 return; |
90 } | 92 } |
91 client_connected_ = true; | 93 client_connected_ = true; |
92 } else { | 94 } else { |
93 NOTREACHED() << "Either local or remote address has to be defined."; | 95 NOTREACHED() << "Either local or remote address has to be defined."; |
94 } | 96 } |
95 if (udp_socket_->SetSendBufferSize(send_buffer_size_) != net::OK) { | 97 if (udp_socket_->SetSendBufferSize(send_buffer_size_) != net::OK) { |
96 LOG(WARNING) << "Failed to set socket send buffer size."; | 98 LOG(WARNING) << "Failed to set socket send buffer size."; |
97 } | 99 } |
98 | 100 |
99 ScheduleReceiveNextPacket(); | 101 ScheduleReceiveNextPacket(); |
100 } | 102 } |
101 | 103 |
102 void UdpTransport::StopReceiving() { | 104 void UdpTransport::StopReceiving() { |
103 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); | 105 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); |
104 packet_receiver_ = PacketReceiverCallbackWithStatus(); | 106 packet_receiver_ = PacketReceiverCallbackWithStatus(); |
105 } | 107 } |
106 | 108 |
107 | 109 |
108 void UdpTransport::SetDscp(net::DiffServCodePoint dscp) { | 110 void UdpTransport::SetDscp(net::DiffServCodePoint dscp) { |
109 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); | 111 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); |
110 next_dscp_value_ = dscp; | 112 next_dscp_value_ = dscp; |
111 } | 113 } |
112 | 114 |
113 #if defined(OS_WIN) | 115 #if defined(OS_WIN) |
114 void UdpTransport::UseNonBlockingIO() { | 116 void UdpTransport::UseNonBlockingIO() { |
115 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); | 117 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); |
118 if (!udp_socket_) | |
119 return; | |
116 udp_socket_->UseNonBlockingIO(); | 120 udp_socket_->UseNonBlockingIO(); |
117 } | 121 } |
118 #endif | 122 #endif |
119 | 123 |
120 void UdpTransport::ScheduleReceiveNextPacket() { | 124 void UdpTransport::ScheduleReceiveNextPacket() { |
121 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); | 125 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); |
122 if (!packet_receiver_.is_null() && !receive_pending_) { | 126 if (!packet_receiver_.is_null() && !receive_pending_) { |
123 receive_pending_ = true; | 127 receive_pending_ = true; |
124 io_thread_proxy_->PostTask(FROM_HERE, | 128 io_thread_proxy_->PostTask(FROM_HERE, |
125 base::Bind(&UdpTransport::ReceiveNextPacket, | 129 base::Bind(&UdpTransport::ReceiveNextPacket, |
126 weak_factory_.GetWeakPtr(), | 130 weak_factory_.GetWeakPtr(), |
127 net::ERR_IO_PENDING)); | 131 net::ERR_IO_PENDING)); |
128 } | 132 } |
129 } | 133 } |
130 | 134 |
131 void UdpTransport::ReceiveNextPacket(int length_or_status) { | 135 void UdpTransport::ReceiveNextPacket(int length_or_status) { |
132 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); | 136 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); |
133 | 137 |
134 if (packet_receiver_.is_null()) | 138 if (packet_receiver_.is_null()) |
135 return; | 139 return; |
140 if (!udp_socket_) | |
141 return; | |
136 | 142 |
137 // Loop while UdpSocket is delivering data synchronously. When it responds | 143 // Loop while UdpSocket is delivering data synchronously. When it responds |
138 // with a "pending" status, break and expect this method to be called back in | 144 // with a "pending" status, break and expect this method to be called back in |
139 // the future when a packet is ready. | 145 // the future when a packet is ready. |
140 while (true) { | 146 while (true) { |
141 if (length_or_status == net::ERR_IO_PENDING) { | 147 if (length_or_status == net::ERR_IO_PENDING) { |
142 next_packet_.reset(new Packet(kMaxPacketSize)); | 148 next_packet_.reset(new Packet(kMaxPacketSize)); |
143 recv_buf_ = new net::WrappedIOBuffer( | 149 recv_buf_ = new net::WrappedIOBuffer( |
144 reinterpret_cast<char*>(&next_packet_->front())); | 150 reinterpret_cast<char*>(&next_packet_->front())); |
145 length_or_status = | 151 length_or_status = |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
182 } else { | 188 } else { |
183 next_packet_->resize(length_or_status); | 189 next_packet_->resize(length_or_status); |
184 packet_receiver_.Run(next_packet_.Pass()); | 190 packet_receiver_.Run(next_packet_.Pass()); |
185 } | 191 } |
186 length_or_status = net::ERR_IO_PENDING; | 192 length_or_status = net::ERR_IO_PENDING; |
187 } | 193 } |
188 } | 194 } |
189 | 195 |
190 bool UdpTransport::SendPacket(PacketRef packet, const base::Closure& cb) { | 196 bool UdpTransport::SendPacket(PacketRef packet, const base::Closure& cb) { |
191 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); | 197 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); |
198 if (!udp_socket_) | |
199 return true; | |
192 | 200 |
193 // Increase byte count no matter the packet was sent or dropped. | 201 // Increase byte count no matter the packet was sent or dropped. |
194 bytes_sent_ += packet->data.size(); | 202 bytes_sent_ += packet->data.size(); |
195 | 203 |
196 DCHECK(!send_pending_); | 204 DCHECK(!send_pending_); |
197 if (send_pending_) { | 205 if (send_pending_) { |
198 VLOG(1) << "Cannot send because of pending IO."; | 206 VLOG(1) << "Cannot send because of pending IO."; |
199 return true; | 207 return true; |
200 } | 208 } |
201 | 209 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
262 } | 270 } |
263 ScheduleReceiveNextPacket(); | 271 ScheduleReceiveNextPacket(); |
264 | 272 |
265 if (!cb.is_null()) { | 273 if (!cb.is_null()) { |
266 cb.Run(); | 274 cb.Run(); |
267 } | 275 } |
268 } | 276 } |
269 | 277 |
270 } // namespace cast | 278 } // namespace cast |
271 } // namespace media | 279 } // namespace media |
OLD | NEW |