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 read_callback_(NULL), | 50 old_read_callback_(NULL), |
51 write_callback_(NULL), | 51 write_callback_(NULL), |
52 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { | 52 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { |
53 scoped_refptr<NetLog::EventParameters> params; | 53 scoped_refptr<NetLog::EventParameters> params; |
54 if (source.is_valid()) | 54 if (source.is_valid()) |
55 params = new NetLogSourceParameter("source_dependency", source); | 55 params = new NetLogSourceParameter("source_dependency", source); |
56 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); | 56 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); |
57 if (bind_type == DatagramSocket::RANDOM_BIND) | 57 if (bind_type == DatagramSocket::RANDOM_BIND) |
58 DCHECK(!rand_int_cb.is_null()); | 58 DCHECK(!rand_int_cb.is_null()); |
59 } | 59 } |
60 | 60 |
61 UDPSocketLibevent::~UDPSocketLibevent() { | 61 UDPSocketLibevent::~UDPSocketLibevent() { |
62 Close(); | 62 Close(); |
63 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); | 63 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); |
64 } | 64 } |
65 | 65 |
66 void UDPSocketLibevent::Close() { | 66 void UDPSocketLibevent::Close() { |
67 DCHECK(CalledOnValidThread()); | 67 DCHECK(CalledOnValidThread()); |
68 | 68 |
69 if (!is_connected()) | 69 if (!is_connected()) |
70 return; | 70 return; |
71 | 71 |
72 // Zero out any pending read/write callback state. | 72 // Zero out any pending read/write callback state. |
73 read_buf_ = NULL; | 73 read_buf_ = NULL; |
74 read_buf_len_ = 0; | 74 read_buf_len_ = 0; |
75 read_callback_ = NULL; | 75 old_read_callback_ = NULL; |
| 76 read_callback_.Reset(); |
76 recv_from_address_ = NULL; | 77 recv_from_address_ = NULL; |
77 write_buf_ = NULL; | 78 write_buf_ = NULL; |
78 write_buf_len_ = 0; | 79 write_buf_len_ = 0; |
79 write_callback_ = NULL; | 80 write_callback_ = NULL; |
80 send_to_address_.reset(); | 81 send_to_address_.reset(); |
81 | 82 |
82 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); | 83 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); |
83 DCHECK(ok); | 84 DCHECK(ok); |
84 ok = write_socket_watcher_.StopWatchingFileDescriptor(); | 85 ok = write_socket_watcher_.StopWatchingFileDescriptor(); |
85 DCHECK(ok); | 86 DCHECK(ok); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 | 133 |
133 *address = *local_address_; | 134 *address = *local_address_; |
134 return OK; | 135 return OK; |
135 } | 136 } |
136 | 137 |
137 int UDPSocketLibevent::Read(IOBuffer* buf, | 138 int UDPSocketLibevent::Read(IOBuffer* buf, |
138 int buf_len, | 139 int buf_len, |
139 OldCompletionCallback* callback) { | 140 OldCompletionCallback* callback) { |
140 return RecvFrom(buf, buf_len, NULL, callback); | 141 return RecvFrom(buf, buf_len, NULL, callback); |
141 } | 142 } |
| 143 int UDPSocketLibevent::Read(IOBuffer* buf, |
| 144 int buf_len, |
| 145 const CompletionCallback& callback) { |
| 146 return RecvFrom(buf, buf_len, NULL, callback); |
| 147 } |
142 | 148 |
143 int UDPSocketLibevent::RecvFrom(IOBuffer* buf, | 149 int UDPSocketLibevent::RecvFrom(IOBuffer* buf, |
144 int buf_len, | 150 int buf_len, |
145 IPEndPoint* address, | 151 IPEndPoint* address, |
146 OldCompletionCallback* callback) { | 152 OldCompletionCallback* callback) { |
147 DCHECK(CalledOnValidThread()); | 153 DCHECK(CalledOnValidThread()); |
148 DCHECK_NE(kInvalidSocket, socket_); | 154 DCHECK_NE(kInvalidSocket, socket_); |
149 DCHECK(!read_callback_); | 155 DCHECK(!old_read_callback_ && read_callback_.is_null()); |
150 DCHECK(!recv_from_address_); | 156 DCHECK(!recv_from_address_); |
151 DCHECK(callback); // Synchronous operation not supported | 157 DCHECK(callback); // Synchronous operation not supported |
152 DCHECK_GT(buf_len, 0); | 158 DCHECK_GT(buf_len, 0); |
153 | 159 |
154 int nread = InternalRecvFrom(buf, buf_len, address); | 160 int nread = InternalRecvFrom(buf, buf_len, address); |
155 if (nread != ERR_IO_PENDING) | 161 if (nread != ERR_IO_PENDING) |
156 return nread; | 162 return nread; |
157 | 163 |
158 if (!MessageLoopForIO::current()->WatchFileDescriptor( | 164 if (!MessageLoopForIO::current()->WatchFileDescriptor( |
159 socket_, true, MessageLoopForIO::WATCH_READ, | 165 socket_, true, MessageLoopForIO::WATCH_READ, |
160 &read_socket_watcher_, &read_watcher_)) { | 166 &read_socket_watcher_, &read_watcher_)) { |
161 PLOG(ERROR) << "WatchFileDescriptor failed on read"; | 167 PLOG(ERROR) << "WatchFileDescriptor failed on read"; |
162 int result = MapSystemError(errno); | 168 int result = MapSystemError(errno); |
163 LogRead(result, NULL, 0, NULL); | 169 LogRead(result, NULL, 0, NULL); |
164 return result; | 170 return result; |
165 } | 171 } |
166 | 172 |
167 read_buf_ = buf; | 173 read_buf_ = buf; |
168 read_buf_len_ = buf_len; | 174 read_buf_len_ = buf_len; |
169 recv_from_address_ = address; | 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) { |
| 183 DCHECK(CalledOnValidThread()); |
| 184 DCHECK_NE(kInvalidSocket, socket_); |
| 185 DCHECK(!old_read_callback_ && read_callback_.is_null()); |
| 186 DCHECK(!recv_from_address_); |
| 187 DCHECK(!callback.is_null()); // Synchronous operation not supported |
| 188 DCHECK_GT(buf_len, 0); |
| 189 |
| 190 int nread = InternalRecvFrom(buf, buf_len, address); |
| 191 if (nread != ERR_IO_PENDING) |
| 192 return nread; |
| 193 |
| 194 if (!MessageLoopForIO::current()->WatchFileDescriptor( |
| 195 socket_, true, MessageLoopForIO::WATCH_READ, |
| 196 &read_socket_watcher_, &read_watcher_)) { |
| 197 PLOG(ERROR) << "WatchFileDescriptor failed on read"; |
| 198 int result = MapSystemError(errno); |
| 199 LogRead(result, NULL, 0, NULL); |
| 200 return result; |
| 201 } |
| 202 |
| 203 read_buf_ = buf; |
| 204 read_buf_len_ = buf_len; |
| 205 recv_from_address_ = address; |
170 read_callback_ = callback; | 206 read_callback_ = callback; |
171 return ERR_IO_PENDING; | 207 return ERR_IO_PENDING; |
172 } | 208 } |
173 | 209 |
174 int UDPSocketLibevent::Write(IOBuffer* buf, | 210 int UDPSocketLibevent::Write(IOBuffer* buf, |
175 int buf_len, | 211 int buf_len, |
176 OldCompletionCallback* callback) { | 212 OldCompletionCallback* callback) { |
177 return SendToOrWrite(buf, buf_len, NULL, callback); | 213 return SendToOrWrite(buf, buf_len, NULL, callback); |
178 } | 214 } |
179 | 215 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 bool UDPSocketLibevent::SetSendBufferSize(int32 size) { | 316 bool UDPSocketLibevent::SetSendBufferSize(int32 size) { |
281 DCHECK(CalledOnValidThread()); | 317 DCHECK(CalledOnValidThread()); |
282 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, | 318 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, |
283 reinterpret_cast<const char*>(&size), sizeof(size)); | 319 reinterpret_cast<const char*>(&size), sizeof(size)); |
284 DCHECK(!rv) << "Could not set socket send buffer size: " << errno; | 320 DCHECK(!rv) << "Could not set socket send buffer size: " << errno; |
285 return rv == 0; | 321 return rv == 0; |
286 } | 322 } |
287 | 323 |
288 void UDPSocketLibevent::DoReadCallback(int rv) { | 324 void UDPSocketLibevent::DoReadCallback(int rv) { |
289 DCHECK_NE(rv, ERR_IO_PENDING); | 325 DCHECK_NE(rv, ERR_IO_PENDING); |
290 DCHECK(read_callback_); | 326 DCHECK(old_read_callback_ || !read_callback_.is_null()); |
291 | 327 |
292 // since Run may result in Read being called, clear read_callback_ up front. | 328 // Since Run may result in Read being called, clear read_callback_ up front. |
293 OldCompletionCallback* c = read_callback_; | 329 if (old_read_callback_) { |
294 read_callback_ = NULL; | 330 OldCompletionCallback* c = old_read_callback_; |
295 c->Run(rv); | 331 old_read_callback_ = NULL; |
| 332 c->Run(rv); |
| 333 } else { |
| 334 CompletionCallback c = read_callback_; |
| 335 read_callback_.Reset(); |
| 336 c.Run(rv); |
| 337 } |
296 } | 338 } |
297 | 339 |
298 void UDPSocketLibevent::DoWriteCallback(int rv) { | 340 void UDPSocketLibevent::DoWriteCallback(int rv) { |
299 DCHECK_NE(rv, ERR_IO_PENDING); | 341 DCHECK_NE(rv, ERR_IO_PENDING); |
300 DCHECK(write_callback_); | 342 DCHECK(write_callback_); |
301 | 343 |
302 // since Run may result in Write being called, clear write_callback_ up front. | 344 // since Run may result in Write being called, clear write_callback_ up front. |
303 OldCompletionCallback* c = write_callback_; | 345 OldCompletionCallback* c = write_callback_; |
304 write_callback_ = NULL; | 346 write_callback_ = NULL; |
305 c->Run(rv); | 347 c->Run(rv); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 | 509 |
468 for (int i = 0; i < kBindRetries; ++i) { | 510 for (int i = 0; i < kBindRetries; ++i) { |
469 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); | 511 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); |
470 if (rv == OK || rv != ERR_ADDRESS_IN_USE) | 512 if (rv == OK || rv != ERR_ADDRESS_IN_USE) |
471 return rv; | 513 return rv; |
472 } | 514 } |
473 return DoBind(IPEndPoint(ip, 0)); | 515 return DoBind(IPEndPoint(ip, 0)); |
474 } | 516 } |
475 | 517 |
476 } // namespace net | 518 } // namespace net |
OLD | NEW |