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

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

Issue 6658027: UDP sockets implementation for windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: - Created 9 years, 9 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 | Annotate | Revision Log
OLDNEW
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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 case ECONNREFUSED: 56 case ECONNREFUSED:
57 return ERR_CONNECTION_REFUSED; 57 return ERR_CONNECTION_REFUSED;
58 case EHOSTUNREACH: 58 case EHOSTUNREACH:
59 case EHOSTDOWN: 59 case EHOSTDOWN:
60 case ENETUNREACH: 60 case ENETUNREACH:
61 return ERR_ADDRESS_UNREACHABLE; 61 return ERR_ADDRESS_UNREACHABLE;
62 case EADDRNOTAVAIL: 62 case EADDRNOTAVAIL:
63 return ERR_ADDRESS_INVALID; 63 return ERR_ADDRESS_INVALID;
64 case EMSGSIZE: 64 case EMSGSIZE:
65 return ERR_MSG_TOO_BIG; 65 return ERR_MSG_TOO_BIG;
66 case ENOTCONN:
67 return ERR_SOCKET_NOT_CONNECTED;
66 case 0: 68 case 0:
67 return OK; 69 return OK;
68 default: 70 default:
69 LOG(WARNING) << "Unknown error " << os_error 71 LOG(WARNING) << "Unknown error " << os_error
70 << " mapped to net::ERR_FAILED"; 72 << " mapped to net::ERR_FAILED";
71 return ERR_FAILED; 73 return ERR_FAILED;
72 } 74 }
73 } 75 }
74 76
75 } // namespace 77 } // namespace
(...skipping 16 matching lines...) Expand all
92 params = new NetLogSourceParameter("source_dependency", source); 94 params = new NetLogSourceParameter("source_dependency", source);
93 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); 95 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params);
94 } 96 }
95 97
96 UDPSocketLibevent::~UDPSocketLibevent() { 98 UDPSocketLibevent::~UDPSocketLibevent() {
97 Close(); 99 Close();
98 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); 100 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL);
99 } 101 }
100 102
101 void UDPSocketLibevent::Close() { 103 void UDPSocketLibevent::Close() {
104 DCHECK(CalledOnValidThread());
105
106 if (read_callback_)
107 DoReadCallback(ERR_ABORTED);
108 if (write_callback_)
109 DoReadCallback(ERR_ABORTED);
110
102 if (!is_connected()) 111 if (!is_connected())
103 return; 112 return;
104 113
114 bool ok = read_socket_watcher_.StopWatchingFileDescriptor();
115 DCHECK(ok);
116 ok = write_socket_watcher_.StopWatchingFileDescriptor();
117 DCHECK(ok);
118
105 if (HANDLE_EINTR(close(socket_)) < 0) 119 if (HANDLE_EINTR(close(socket_)) < 0)
106 PLOG(ERROR) << "close"; 120 PLOG(ERROR) << "close";
107 121
108 socket_ = kInvalidSocket; 122 socket_ = kInvalidSocket;
109 } 123 }
110 124
111 int UDPSocketLibevent::GetPeerAddress(IPEndPoint* address) const { 125 int UDPSocketLibevent::GetPeerAddress(IPEndPoint* address) const {
112 DCHECK(CalledOnValidThread()); 126 DCHECK(CalledOnValidThread());
113 DCHECK(address); 127 DCHECK(address);
114 if (!is_connected()) 128 if (!is_connected())
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 168
155 int UDPSocketLibevent::Read(IOBuffer* buf, 169 int UDPSocketLibevent::Read(IOBuffer* buf,
156 int buf_len, 170 int buf_len,
157 CompletionCallback* callback) { 171 CompletionCallback* callback) {
158 DCHECK(CalledOnValidThread()); 172 DCHECK(CalledOnValidThread());
159 DCHECK_NE(kInvalidSocket, socket_); 173 DCHECK_NE(kInvalidSocket, socket_);
160 DCHECK(!read_callback_); 174 DCHECK(!read_callback_);
161 DCHECK(callback); // Synchronous operation not supported 175 DCHECK(callback); // Synchronous operation not supported
162 DCHECK_GT(buf_len, 0); 176 DCHECK_GT(buf_len, 0);
163 177
164 read_buf_ = buf; 178 int nread = InternalRead(buf, buf_len);
165 read_buf_len_ = buf_len;
166
167 int nread = InternalRead();
168 if (nread != ERR_IO_PENDING) 179 if (nread != ERR_IO_PENDING)
169 return nread; 180 return nread;
170 181
171 if (!MessageLoopForIO::current()->WatchFileDescriptor( 182 if (!MessageLoopForIO::current()->WatchFileDescriptor(
172 socket_, true, MessageLoopForIO::WATCH_READ, 183 socket_, true, MessageLoopForIO::WATCH_READ,
173 &read_socket_watcher_, &read_watcher_)) { 184 &read_socket_watcher_, &read_watcher_)) {
174 PLOG(ERROR) << "WatchFileDescriptor failed on read"; 185 PLOG(ERROR) << "WatchFileDescriptor failed on read";
175 return MapPosixError(errno); 186 return MapPosixError(errno);
176 } 187 }
177 188
189 read_buf_ = buf;
190 read_buf_len_ = buf_len;
178 read_callback_ = callback; 191 read_callback_ = callback;
179 return ERR_IO_PENDING; 192 return ERR_IO_PENDING;
180 } 193 }
181 194
182 int UDPSocketLibevent::RecvFrom(IOBuffer* buf, 195 int UDPSocketLibevent::RecvFrom(IOBuffer* buf,
183 int buf_len, 196 int buf_len,
184 IPEndPoint* address, 197 IPEndPoint* address,
185 CompletionCallback* callback) { 198 CompletionCallback* callback) {
186 DCHECK(!recv_from_address_); 199 DCHECK(!recv_from_address_);
187 recv_from_address_ = address; 200 recv_from_address_ = address;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 write_buf_len_ = buf_len; 238 write_buf_len_ = buf_len;
226 write_callback_ = callback; 239 write_callback_ = callback;
227 return ERR_IO_PENDING; 240 return ERR_IO_PENDING;
228 } 241 }
229 242
230 int UDPSocketLibevent::Connect(const IPEndPoint& address) { 243 int UDPSocketLibevent::Connect(const IPEndPoint& address) {
231 DCHECK(!is_connected()); 244 DCHECK(!is_connected());
232 DCHECK(!remote_address_.get()); 245 DCHECK(!remote_address_.get());
233 int rv = CreateSocket(address); 246 int rv = CreateSocket(address);
234 if (rv < 0) 247 if (rv < 0)
235 return MapPosixError(rv); 248 return rv;
236 249
237 struct sockaddr_storage addr_storage; 250 struct sockaddr_storage addr_storage;
238 size_t addr_len = sizeof(addr_storage); 251 size_t addr_len = sizeof(addr_storage);
239 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); 252 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage);
240 if (!address.ToSockAddr(addr, &addr_len)) 253 if (!address.ToSockAddr(addr, &addr_len))
241 return ERR_FAILED; 254 return ERR_FAILED;
242 255
243 rv = HANDLE_EINTR(connect(socket_, addr, addr_len)); 256 rv = HANDLE_EINTR(connect(socket_, addr, addr_len));
244 if (rv < 0) 257 if (rv < 0)
245 return MapPosixError(rv); 258 return MapPosixError(errno);
246 259
247 remote_address_.reset(new IPEndPoint(address)); 260 remote_address_.reset(new IPEndPoint(address));
248 return rv; 261 return rv;
249 } 262 }
250 263
251 int UDPSocketLibevent::Bind(const IPEndPoint& address) { 264 int UDPSocketLibevent::Bind(const IPEndPoint& address) {
252 DCHECK(!is_connected()); 265 DCHECK(!is_connected());
253 DCHECK(!local_address_.get()); 266 DCHECK(!local_address_.get());
254 int rv = CreateSocket(address); 267 int rv = CreateSocket(address);
255 if (rv < 0) 268 if (rv < 0)
256 return MapPosixError(rv); 269 return rv;
257 270
258 struct sockaddr_storage addr_storage; 271 struct sockaddr_storage addr_storage;
259 size_t addr_len = sizeof(addr_storage); 272 size_t addr_len = sizeof(addr_storage);
260 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); 273 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage);
261 if (!address.ToSockAddr(addr, &addr_len)) 274 if (!address.ToSockAddr(addr, &addr_len))
262 return ERR_FAILED; 275 return ERR_FAILED;
263 276
264 rv = bind(socket_, addr, addr_len); 277 rv = bind(socket_, addr, addr_len);
265 if (rv < 0) 278 if (rv < 0)
266 return MapPosixError(rv); 279 return MapPosixError(errno);
267 280
268 local_address_.reset(new IPEndPoint(address)); 281 local_address_.reset(new IPEndPoint(address));
269 return rv; 282 return rv;
270 } 283 }
271 284
272 void UDPSocketLibevent::DoReadCallback(int rv) { 285 void UDPSocketLibevent::DoReadCallback(int rv) {
273 DCHECK_NE(rv, ERR_IO_PENDING); 286 DCHECK_NE(rv, ERR_IO_PENDING);
274 DCHECK(read_callback_); 287 DCHECK(read_callback_);
275 288
276 // since Run may result in Read being called, clear read_callback_ up front. 289 // since Run may result in Read being called, clear read_callback_ up front.
277 CompletionCallback* c = read_callback_; 290 CompletionCallback* c = read_callback_;
278 read_callback_ = NULL; 291 read_callback_ = NULL;
279 recv_from_address_ = NULL; 292 recv_from_address_ = NULL;
280 c->Run(rv); 293 c->Run(rv);
281 } 294 }
282 295
283 void UDPSocketLibevent::DoWriteCallback(int rv) { 296 void UDPSocketLibevent::DoWriteCallback(int rv) {
284 DCHECK_NE(rv, ERR_IO_PENDING); 297 DCHECK_NE(rv, ERR_IO_PENDING);
285 DCHECK(write_callback_); 298 DCHECK(write_callback_);
286 299
287 // 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.
288 CompletionCallback* c = write_callback_; 301 CompletionCallback* c = write_callback_;
289 write_callback_ = NULL; 302 write_callback_ = NULL;
290 send_to_address_.reset(); 303 send_to_address_.reset();
291 c->Run(rv); 304 c->Run(rv);
292 } 305 }
293 306
294 void UDPSocketLibevent::DidCompleteRead() { 307 void UDPSocketLibevent::DidCompleteRead() {
295 int result = InternalRead(); 308 int result = InternalRead(read_buf_, read_buf_len_);
296 if (result != ERR_IO_PENDING) { 309 if (result != ERR_IO_PENDING) {
297 read_buf_ = NULL; 310 read_buf_ = NULL;
298 read_buf_len_ = 0; 311 read_buf_len_ = 0;
299 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); 312 bool ok = read_socket_watcher_.StopWatchingFileDescriptor();
300 DCHECK(ok); 313 DCHECK(ok);
301 DoReadCallback(result); 314 DoReadCallback(result);
302 } 315 }
303 } 316 }
304 317
305 int UDPSocketLibevent::CreateSocket(const IPEndPoint& address) { 318 int UDPSocketLibevent::CreateSocket(const IPEndPoint& address) {
306 socket_ = socket(address.GetFamily(), SOCK_DGRAM, 0); 319 socket_ = socket(address.GetFamily(), SOCK_DGRAM, 0);
307 if (socket_ == kInvalidSocket) 320 if (socket_ == kInvalidSocket)
308 return errno; 321 return MapPosixError(errno);
309 if (SetNonBlocking(socket_)) { 322 if (SetNonBlocking(socket_)) {
310 const int err = errno; 323 const int err = MapPosixError(errno);
311 Close(); 324 Close();
312 return err; 325 return err;
313 } 326 }
314 return OK; 327 return OK;
315 } 328 }
316 329
317 void UDPSocketLibevent::DidCompleteWrite() { 330 void UDPSocketLibevent::DidCompleteWrite() {
318 int result = InternalWrite(write_buf_, write_buf_len_); 331 int result = InternalWrite(write_buf_, write_buf_len_);
319 if (result >= 0) { 332 if (result >= 0) {
320 static base::StatsCounter write_bytes("udp.write_bytes"); 333 static base::StatsCounter write_bytes("udp.write_bytes");
321 write_bytes.Add(result); 334 write_bytes.Add(result);
322 } else { 335 } else {
323 result = MapPosixError(errno); 336 result = MapPosixError(errno);
324 } 337 }
325 338
326 if (result != ERR_IO_PENDING) { 339 if (result != ERR_IO_PENDING) {
327 write_buf_ = NULL; 340 write_buf_ = NULL;
328 write_buf_len_ = 0; 341 write_buf_len_ = 0;
329 write_socket_watcher_.StopWatchingFileDescriptor(); 342 write_socket_watcher_.StopWatchingFileDescriptor();
330 DoWriteCallback(result); 343 DoWriteCallback(result);
331 } 344 }
332 } 345 }
333 346
334 int UDPSocketLibevent::InternalRead() { 347 int UDPSocketLibevent::InternalRead(IOBuffer* buf, int buf_len) {
335 int bytes_transferred; 348 int bytes_transferred;
336 int flags = 0; 349 int flags = 0;
337 350
338 struct sockaddr_storage addr_storage; 351 struct sockaddr_storage addr_storage;
339 socklen_t addr_len = sizeof(addr_storage); 352 socklen_t addr_len = sizeof(addr_storage);
340 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); 353 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage);
341 354
342 bytes_transferred = 355 bytes_transferred =
343 HANDLE_EINTR(recvfrom(socket_, 356 HANDLE_EINTR(recvfrom(socket_,
344 read_buf_->data(), 357 buf->data(),
345 read_buf_len_, 358 buf_len,
346 flags, 359 flags,
347 addr, 360 addr,
348 &addr_len)); 361 &addr_len));
349 int result; 362 int result;
350 if (bytes_transferred >= 0) { 363 if (bytes_transferred >= 0) {
351 result = bytes_transferred; 364 result = bytes_transferred;
352 static base::StatsCounter read_bytes("udp.read_bytes"); 365 static base::StatsCounter read_bytes("udp.read_bytes");
353 read_bytes.Add(bytes_transferred); 366 read_bytes.Add(bytes_transferred);
354 if (recv_from_address_) { 367 if (recv_from_address_) {
355 if (!recv_from_address_->FromSockAddr(addr, addr_len)) 368 if (!recv_from_address_->FromSockAddr(addr, addr_len))
356 result = ERR_FAILED; 369 result = ERR_FAILED;
357 } 370 }
358 } else { 371 } else {
359 result = MapPosixError(errno); 372 result = MapPosixError(errno);
360 } 373 }
361 return result; 374 return result;
362 } 375 }
376
363 int UDPSocketLibevent::InternalWrite(IOBuffer* buf, int buf_len) { 377 int UDPSocketLibevent::InternalWrite(IOBuffer* buf, int buf_len) {
364 struct sockaddr_storage addr_storage; 378 struct sockaddr_storage addr_storage;
365 size_t addr_len = sizeof(addr_storage); 379 size_t addr_len = sizeof(addr_storage);
366 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); 380 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage);
367 381
368 if (!send_to_address_.get()) { 382 if (!send_to_address_.get()) {
369 addr = NULL; 383 addr = NULL;
370 addr_len = 0; 384 addr_len = 0;
371 } else { 385 } else {
372 if (!send_to_address_->ToSockAddr(addr, &addr_len)) 386 if (!send_to_address_->ToSockAddr(addr, &addr_len))
373 return ERR_FAILED; 387 return ERR_FAILED;
374 } 388 }
375 389
376 return HANDLE_EINTR(sendto(socket_, 390 return HANDLE_EINTR(sendto(socket_,
377 buf->data(), 391 buf->data(),
378 buf_len, 392 buf_len,
379 0, 393 0,
380 addr, 394 addr,
381 addr_len)); 395 addr_len));
382 } 396 }
383 397
384 } // namespace net 398 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698