OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_libevent.h" | 5 #include "net/udp/udp_socket_libevent.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <netdb.h> | 9 #include <netdb.h> |
10 #include <sys/socket.h> | 10 #include <sys/socket.h> |
(...skipping 29 matching lines...) Expand all Loading... |
40 net::NetLog* net_log, | 40 net::NetLog* net_log, |
41 const net::NetLog::Source& source) | 41 const net::NetLog::Source& source) |
42 : socket_(kInvalidSocket), | 42 : socket_(kInvalidSocket), |
43 bind_type_(bind_type), | 43 bind_type_(bind_type), |
44 rand_int_cb_(rand_int_cb), | 44 rand_int_cb_(rand_int_cb), |
45 read_watcher_(this), | 45 read_watcher_(this), |
46 write_watcher_(this), | 46 write_watcher_(this), |
47 read_buf_len_(0), | 47 read_buf_len_(0), |
48 recv_from_address_(NULL), | 48 recv_from_address_(NULL), |
49 write_buf_len_(0), | 49 write_buf_len_(0), |
50 old_read_callback_(NULL), | |
51 write_callback_(NULL), | |
52 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { | 50 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { |
53 scoped_refptr<NetLog::EventParameters> params; | 51 scoped_refptr<NetLog::EventParameters> params; |
54 if (source.is_valid()) | 52 if (source.is_valid()) |
55 params = new NetLogSourceParameter("source_dependency", source); | 53 params = new NetLogSourceParameter("source_dependency", source); |
56 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); | 54 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); |
57 if (bind_type == DatagramSocket::RANDOM_BIND) | 55 if (bind_type == DatagramSocket::RANDOM_BIND) |
58 DCHECK(!rand_int_cb.is_null()); | 56 DCHECK(!rand_int_cb.is_null()); |
59 } | 57 } |
60 | 58 |
61 UDPSocketLibevent::~UDPSocketLibevent() { | 59 UDPSocketLibevent::~UDPSocketLibevent() { |
62 Close(); | 60 Close(); |
63 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); | 61 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); |
64 } | 62 } |
65 | 63 |
66 void UDPSocketLibevent::Close() { | 64 void UDPSocketLibevent::Close() { |
67 DCHECK(CalledOnValidThread()); | 65 DCHECK(CalledOnValidThread()); |
68 | 66 |
69 if (!is_connected()) | 67 if (!is_connected()) |
70 return; | 68 return; |
71 | 69 |
72 // Zero out any pending read/write callback state. | 70 // Zero out any pending read/write callback state. |
73 read_buf_ = NULL; | 71 read_buf_ = NULL; |
74 read_buf_len_ = 0; | 72 read_buf_len_ = 0; |
75 old_read_callback_ = NULL; | |
76 read_callback_.Reset(); | 73 read_callback_.Reset(); |
77 recv_from_address_ = NULL; | 74 recv_from_address_ = NULL; |
78 write_buf_ = NULL; | 75 write_buf_ = NULL; |
79 write_buf_len_ = 0; | 76 write_buf_len_ = 0; |
80 write_callback_ = NULL; | 77 write_callback_.Reset(); |
81 send_to_address_.reset(); | 78 send_to_address_.reset(); |
82 | 79 |
83 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); | 80 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); |
84 DCHECK(ok); | 81 DCHECK(ok); |
85 ok = write_socket_watcher_.StopWatchingFileDescriptor(); | 82 ok = write_socket_watcher_.StopWatchingFileDescriptor(); |
86 DCHECK(ok); | 83 DCHECK(ok); |
87 | 84 |
88 if (HANDLE_EINTR(close(socket_)) < 0) | 85 if (HANDLE_EINTR(close(socket_)) < 0) |
89 PLOG(ERROR) << "close"; | 86 PLOG(ERROR) << "close"; |
90 | 87 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 return ERR_FAILED; | 127 return ERR_FAILED; |
131 local_address_.reset(address.release()); | 128 local_address_.reset(address.release()); |
132 } | 129 } |
133 | 130 |
134 *address = *local_address_; | 131 *address = *local_address_; |
135 return OK; | 132 return OK; |
136 } | 133 } |
137 | 134 |
138 int UDPSocketLibevent::Read(IOBuffer* buf, | 135 int UDPSocketLibevent::Read(IOBuffer* buf, |
139 int buf_len, | 136 int buf_len, |
140 OldCompletionCallback* callback) { | |
141 return RecvFrom(buf, buf_len, NULL, callback); | |
142 } | |
143 int UDPSocketLibevent::Read(IOBuffer* buf, | |
144 int buf_len, | |
145 const CompletionCallback& callback) { | 137 const CompletionCallback& callback) { |
146 return RecvFrom(buf, buf_len, NULL, callback); | 138 return RecvFrom(buf, buf_len, NULL, callback); |
147 } | 139 } |
148 | 140 |
149 int UDPSocketLibevent::RecvFrom(IOBuffer* buf, | 141 int UDPSocketLibevent::RecvFrom(IOBuffer* buf, |
150 int buf_len, | 142 int buf_len, |
151 IPEndPoint* address, | 143 IPEndPoint* address, |
152 OldCompletionCallback* callback) { | |
153 DCHECK(CalledOnValidThread()); | |
154 DCHECK_NE(kInvalidSocket, socket_); | |
155 DCHECK(!old_read_callback_ && read_callback_.is_null()); | |
156 DCHECK(!recv_from_address_); | |
157 DCHECK(callback); // Synchronous operation not supported | |
158 DCHECK_GT(buf_len, 0); | |
159 | |
160 int nread = InternalRecvFrom(buf, buf_len, address); | |
161 if (nread != ERR_IO_PENDING) | |
162 return nread; | |
163 | |
164 if (!MessageLoopForIO::current()->WatchFileDescriptor( | |
165 socket_, true, MessageLoopForIO::WATCH_READ, | |
166 &read_socket_watcher_, &read_watcher_)) { | |
167 PLOG(ERROR) << "WatchFileDescriptor failed on read"; | |
168 int result = MapSystemError(errno); | |
169 LogRead(result, NULL, 0, NULL); | |
170 return result; | |
171 } | |
172 | |
173 read_buf_ = buf; | |
174 read_buf_len_ = buf_len; | |
175 recv_from_address_ = address; | |
176 old_read_callback_ = callback; | |
177 return ERR_IO_PENDING; | |
178 } | |
179 int UDPSocketLibevent::RecvFrom(IOBuffer* buf, | |
180 int buf_len, | |
181 IPEndPoint* address, | |
182 const CompletionCallback& callback) { | 144 const CompletionCallback& callback) { |
183 DCHECK(CalledOnValidThread()); | 145 DCHECK(CalledOnValidThread()); |
184 DCHECK_NE(kInvalidSocket, socket_); | 146 DCHECK_NE(kInvalidSocket, socket_); |
185 DCHECK(!old_read_callback_ && read_callback_.is_null()); | 147 DCHECK(read_callback_.is_null()); |
186 DCHECK(!recv_from_address_); | 148 DCHECK(!recv_from_address_); |
187 DCHECK(!callback.is_null()); // Synchronous operation not supported | 149 DCHECK(!callback.is_null()); // Synchronous operation not supported |
188 DCHECK_GT(buf_len, 0); | 150 DCHECK_GT(buf_len, 0); |
189 | 151 |
190 int nread = InternalRecvFrom(buf, buf_len, address); | 152 int nread = InternalRecvFrom(buf, buf_len, address); |
191 if (nread != ERR_IO_PENDING) | 153 if (nread != ERR_IO_PENDING) |
192 return nread; | 154 return nread; |
193 | 155 |
194 if (!MessageLoopForIO::current()->WatchFileDescriptor( | 156 if (!MessageLoopForIO::current()->WatchFileDescriptor( |
195 socket_, true, MessageLoopForIO::WATCH_READ, | 157 socket_, true, MessageLoopForIO::WATCH_READ, |
196 &read_socket_watcher_, &read_watcher_)) { | 158 &read_socket_watcher_, &read_watcher_)) { |
197 PLOG(ERROR) << "WatchFileDescriptor failed on read"; | 159 PLOG(ERROR) << "WatchFileDescriptor failed on read"; |
198 int result = MapSystemError(errno); | 160 int result = MapSystemError(errno); |
199 LogRead(result, NULL, 0, NULL); | 161 LogRead(result, NULL, 0, NULL); |
200 return result; | 162 return result; |
201 } | 163 } |
202 | 164 |
203 read_buf_ = buf; | 165 read_buf_ = buf; |
204 read_buf_len_ = buf_len; | 166 read_buf_len_ = buf_len; |
205 recv_from_address_ = address; | 167 recv_from_address_ = address; |
206 read_callback_ = callback; | 168 read_callback_ = callback; |
207 return ERR_IO_PENDING; | 169 return ERR_IO_PENDING; |
208 } | 170 } |
209 | 171 |
210 int UDPSocketLibevent::Write(IOBuffer* buf, | 172 int UDPSocketLibevent::Write(IOBuffer* buf, |
211 int buf_len, | 173 int buf_len, |
212 OldCompletionCallback* callback) { | 174 const CompletionCallback& callback) { |
213 return SendToOrWrite(buf, buf_len, NULL, callback); | 175 return SendToOrWrite(buf, buf_len, NULL, callback); |
214 } | 176 } |
215 | 177 |
216 int UDPSocketLibevent::SendTo(IOBuffer* buf, | 178 int UDPSocketLibevent::SendTo(IOBuffer* buf, |
217 int buf_len, | 179 int buf_len, |
218 const IPEndPoint& address, | 180 const IPEndPoint& address, |
219 OldCompletionCallback* callback) { | 181 const CompletionCallback& callback) { |
220 return SendToOrWrite(buf, buf_len, &address, callback); | 182 return SendToOrWrite(buf, buf_len, &address, callback); |
221 } | 183 } |
222 | 184 |
223 int UDPSocketLibevent::SendToOrWrite(IOBuffer* buf, | 185 int UDPSocketLibevent::SendToOrWrite(IOBuffer* buf, |
224 int buf_len, | 186 int buf_len, |
225 const IPEndPoint* address, | 187 const IPEndPoint* address, |
226 OldCompletionCallback* callback) { | 188 const CompletionCallback& callback) { |
227 DCHECK(CalledOnValidThread()); | 189 DCHECK(CalledOnValidThread()); |
228 DCHECK_NE(kInvalidSocket, socket_); | 190 DCHECK_NE(kInvalidSocket, socket_); |
229 DCHECK(!write_callback_); | 191 DCHECK(write_callback_.is_null()); |
230 DCHECK(callback); // Synchronous operation not supported | 192 DCHECK(!callback.is_null()); // Synchronous operation not supported |
231 DCHECK_GT(buf_len, 0); | 193 DCHECK_GT(buf_len, 0); |
232 | 194 |
233 int result = InternalSendTo(buf, buf_len, address); | 195 int result = InternalSendTo(buf, buf_len, address); |
234 if (result != ERR_IO_PENDING) | 196 if (result != ERR_IO_PENDING) |
235 return result; | 197 return result; |
236 | 198 |
237 if (!MessageLoopForIO::current()->WatchFileDescriptor( | 199 if (!MessageLoopForIO::current()->WatchFileDescriptor( |
238 socket_, true, MessageLoopForIO::WATCH_WRITE, | 200 socket_, true, MessageLoopForIO::WATCH_WRITE, |
239 &write_socket_watcher_, &write_watcher_)) { | 201 &write_socket_watcher_, &write_watcher_)) { |
240 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno; | 202 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 bool UDPSocketLibevent::SetSendBufferSize(int32 size) { | 278 bool UDPSocketLibevent::SetSendBufferSize(int32 size) { |
317 DCHECK(CalledOnValidThread()); | 279 DCHECK(CalledOnValidThread()); |
318 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, | 280 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, |
319 reinterpret_cast<const char*>(&size), sizeof(size)); | 281 reinterpret_cast<const char*>(&size), sizeof(size)); |
320 DCHECK(!rv) << "Could not set socket send buffer size: " << errno; | 282 DCHECK(!rv) << "Could not set socket send buffer size: " << errno; |
321 return rv == 0; | 283 return rv == 0; |
322 } | 284 } |
323 | 285 |
324 void UDPSocketLibevent::DoReadCallback(int rv) { | 286 void UDPSocketLibevent::DoReadCallback(int rv) { |
325 DCHECK_NE(rv, ERR_IO_PENDING); | 287 DCHECK_NE(rv, ERR_IO_PENDING); |
326 DCHECK(old_read_callback_ || !read_callback_.is_null()); | 288 DCHECK(!read_callback_.is_null()); |
327 | 289 |
328 // Since Run may result in Read being called, clear read_callback_ up front. | 290 // since Run may result in Read being called, clear read_callback_ up front. |
329 if (old_read_callback_) { | 291 CompletionCallback c = read_callback_; |
330 OldCompletionCallback* c = old_read_callback_; | 292 read_callback_.Reset(); |
331 old_read_callback_ = NULL; | 293 c.Run(rv); |
332 c->Run(rv); | |
333 } else { | |
334 CompletionCallback c = read_callback_; | |
335 read_callback_.Reset(); | |
336 c.Run(rv); | |
337 } | |
338 } | 294 } |
339 | 295 |
340 void UDPSocketLibevent::DoWriteCallback(int rv) { | 296 void UDPSocketLibevent::DoWriteCallback(int rv) { |
341 DCHECK_NE(rv, ERR_IO_PENDING); | 297 DCHECK_NE(rv, ERR_IO_PENDING); |
342 DCHECK(write_callback_); | 298 DCHECK(!write_callback_.is_null()); |
343 | 299 |
344 // since Run may result in Write being called, clear write_callback_ up front. | 300 // since Run may result in Write being called, clear write_callback_ up front. |
345 OldCompletionCallback* c = write_callback_; | 301 CompletionCallback c = write_callback_; |
346 write_callback_ = NULL; | 302 write_callback_.Reset(); |
347 c->Run(rv); | 303 c.Run(rv); |
348 } | 304 } |
349 | 305 |
350 void UDPSocketLibevent::DidCompleteRead() { | 306 void UDPSocketLibevent::DidCompleteRead() { |
351 int result = InternalRecvFrom(read_buf_, read_buf_len_, recv_from_address_); | 307 int result = InternalRecvFrom(read_buf_, read_buf_len_, recv_from_address_); |
352 if (result != ERR_IO_PENDING) { | 308 if (result != ERR_IO_PENDING) { |
353 read_buf_ = NULL; | 309 read_buf_ = NULL; |
354 read_buf_len_ = 0; | 310 read_buf_len_ = 0; |
355 recv_from_address_ = NULL; | 311 recv_from_address_ = NULL; |
356 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); | 312 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); |
357 DCHECK(ok); | 313 DCHECK(ok); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 | 465 |
510 for (int i = 0; i < kBindRetries; ++i) { | 466 for (int i = 0; i < kBindRetries; ++i) { |
511 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); | 467 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); |
512 if (rv == OK || rv != ERR_ADDRESS_IN_USE) | 468 if (rv == OK || rv != ERR_ADDRESS_IN_USE) |
513 return rv; | 469 return rv; |
514 } | 470 } |
515 return DoBind(IPEndPoint(ip, 0)); | 471 return DoBind(IPEndPoint(ip, 0)); |
516 } | 472 } |
517 | 473 |
518 } // namespace net | 474 } // namespace net |
OLD | NEW |