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

Side by Side Diff: runtime/bin/socket_linux.cc

Issue 171503009: Remove SocketData and now only pass the dart port to epoll. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 10 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
« no previous file with comments | « runtime/bin/socket.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "platform/globals.h" 5 #include "platform/globals.h"
6 #if defined(TARGET_OS_LINUX) 6 #if defined(TARGET_OS_LINUX)
7 7
8 #include <errno.h> // NOLINT 8 #include <errno.h> // NOLINT
9 #include <stdio.h> // NOLINT 9 #include <stdio.h> // NOLINT
10 #include <stdlib.h> // NOLINT 10 #include <stdlib.h> // NOLINT
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 53
54 54
55 bool Socket::Initialize() { 55 bool Socket::Initialize() {
56 // Nothing to do on Linux. 56 // Nothing to do on Linux.
57 return true; 57 return true;
58 } 58 }
59 59
60 60
61 intptr_t Socket::Create(RawAddr addr) { 61 intptr_t Socket::Create(RawAddr addr) {
62 intptr_t fd; 62 intptr_t fd;
63 fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(socket(addr.ss.ss_family, SOCK_STREAM, 63 fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(socket(
64 0)); 64 addr.ss.ss_family, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
65 if (fd < 0) { 65 if (fd < 0) {
66 const int kBufferSize = 1024; 66 const int kBufferSize = 1024;
67 char error_buf[kBufferSize]; 67 char error_buf[kBufferSize];
68 Log::PrintErr("Error Create: %s\n", 68 Log::PrintErr("Error Create: %s\n",
69 strerror_r(errno, error_buf, kBufferSize)); 69 strerror_r(errno, error_buf, kBufferSize));
70 return -1; 70 return -1;
71 } 71 }
72
73 FDUtils::SetCloseOnExec(fd);
74 return fd; 72 return fd;
75 } 73 }
76 74
77 75
78 intptr_t Socket::Connect(intptr_t fd, RawAddr addr, const intptr_t port) { 76 intptr_t Socket::Connect(intptr_t fd, RawAddr addr, const intptr_t port) {
79 SocketAddress::SetAddrPort(&addr, port); 77 SocketAddress::SetAddrPort(&addr, port);
80 intptr_t result = TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 78 intptr_t result = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(
81 connect(fd, 79 connect(fd,
82 &addr.addr, 80 &addr.addr,
83 SocketAddress::GetAddrLength(&addr))); 81 SocketAddress::GetAddrLength(&addr)));
84 if (result == 0 || errno == EINPROGRESS) { 82 if (result == 0 || errno == EINPROGRESS) {
85 return fd; 83 return fd;
86 } 84 }
87 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd)); 85 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd));
88 return -1; 86 return -1;
89 } 87 }
90 88
91 89
92 intptr_t Socket::CreateConnect(RawAddr addr, const intptr_t port) { 90 intptr_t Socket::CreateConnect(RawAddr addr, const intptr_t port) {
93 intptr_t fd = Socket::Create(addr); 91 intptr_t fd = Socket::Create(addr);
94 if (fd < 0) { 92 if (fd < 0) {
95 return fd; 93 return fd;
96 } 94 }
97
98 Socket::SetNonBlocking(fd);
99
100 return Socket::Connect(fd, addr, port); 95 return Socket::Connect(fd, addr, port);
101 } 96 }
102 97
103 98
104 intptr_t Socket::Available(intptr_t fd) { 99 intptr_t Socket::Available(intptr_t fd) {
105 return FDUtils::AvailableBytes(fd); 100 return FDUtils::AvailableBytes(fd);
106 } 101 }
107 102
108 103
109 int Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) { 104 int Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 result = inet_pton(AF_INET6, address, &addr->in6.sin6_addr); 303 result = inet_pton(AF_INET6, address, &addr->in6.sin6_addr);
309 } 304 }
310 return result == 1; 305 return result == 1;
311 } 306 }
312 307
313 308
314 intptr_t Socket::CreateBindDatagram( 309 intptr_t Socket::CreateBindDatagram(
315 RawAddr* addr, intptr_t port, bool reuseAddress) { 310 RawAddr* addr, intptr_t port, bool reuseAddress) {
316 intptr_t fd; 311 intptr_t fd;
317 312
318 fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 313 fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(socket(
319 socket(addr->addr.sa_family, SOCK_DGRAM, IPPROTO_UDP)); 314 addr->addr.sa_family,
315 SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
316 IPPROTO_UDP));
320 if (fd < 0) return -1; 317 if (fd < 0) return -1;
321 318
322 FDUtils::SetCloseOnExec(fd);
323
324 if (reuseAddress) { 319 if (reuseAddress) {
325 int optval = 1; 320 int optval = 1;
326 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 321 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(
327 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); 322 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));
328 } 323 }
329 324
330 SocketAddress::SetAddrPort(addr, port); 325 SocketAddress::SetAddrPort(addr, port);
331 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 326 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(
332 bind(fd, 327 bind(fd,
333 &addr->addr, 328 &addr->addr,
334 SocketAddress::GetAddrLength(addr))) < 0) { 329 SocketAddress::GetAddrLength(addr))) < 0) {
335 TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd)); 330 TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd));
336 return -1; 331 return -1;
337 } 332 }
338
339 Socket::SetNonBlocking(fd);
340 return fd; 333 return fd;
341 } 334 }
342 335
343 336
344 static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) { 337 static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) {
345 if (ifa->ifa_addr == NULL) { 338 if (ifa->ifa_addr == NULL) {
346 // OpenVPN's virtual device tun0. 339 // OpenVPN's virtual device tun0.
347 return false; 340 return false;
348 } 341 }
349 int family = ifa->ifa_addr->sa_family; 342 int family = ifa->ifa_addr->sa_family;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 return addresses; 384 return addresses;
392 } 385 }
393 386
394 387
395 intptr_t ServerSocket::CreateBindListen(RawAddr addr, 388 intptr_t ServerSocket::CreateBindListen(RawAddr addr,
396 intptr_t port, 389 intptr_t port,
397 intptr_t backlog, 390 intptr_t backlog,
398 bool v6_only) { 391 bool v6_only) {
399 intptr_t fd; 392 intptr_t fd;
400 393
401 fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(socket(addr.ss.ss_family, SOCK_STREAM, 394 fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(socket(
402 0)); 395 addr.ss.ss_family, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0));
403 if (fd < 0) return -1; 396 if (fd < 0) return -1;
404 397
405 FDUtils::SetCloseOnExec(fd);
406
407 int optval = 1; 398 int optval = 1;
408 TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 399 TEMP_FAILURE_RETRY_BLOCK_SIGNALS(
409 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); 400 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));
410 401
411 if (addr.ss.ss_family == AF_INET6) { 402 if (addr.ss.ss_family == AF_INET6) {
412 optval = v6_only ? 1 : 0; 403 optval = v6_only ? 1 : 0;
413 TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 404 TEMP_FAILURE_RETRY_BLOCK_SIGNALS(
414 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval))); 405 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval)));
415 } 406 }
416 407
(...skipping 16 matching lines...) Expand all
433 errno = err; 424 errno = err;
434 return new_fd; 425 return new_fd;
435 } 426 }
436 427
437 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 428 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(
438 listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) { 429 listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) {
439 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd)); 430 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd));
440 return -1; 431 return -1;
441 } 432 }
442 433
443 Socket::SetNonBlocking(fd);
444 return fd; 434 return fd;
445 } 435 }
446 436
447 437
448 static bool IsTemporaryAcceptError(int error) { 438 static bool IsTemporaryAcceptError(int error) {
449 // On Linux a number of protocol errors should be treated as EAGAIN. 439 // On Linux a number of protocol errors should be treated as EAGAIN.
450 // These are the ones for TCP/IP. 440 // These are the ones for TCP/IP.
451 return (error == EAGAIN) || (error == ENETDOWN) || (error == EPROTO) || 441 return (error == EAGAIN) || (error == ENETDOWN) || (error == EPROTO) ||
452 (error == ENOPROTOOPT) || (error == EHOSTDOWN) || (error == ENONET) || 442 (error == ENOPROTOOPT) || (error == EHOSTDOWN) || (error == ENONET) ||
453 (error == EHOSTUNREACH) || (error == EOPNOTSUPP) || 443 (error == EHOSTUNREACH) || (error == EOPNOTSUPP) ||
454 (error == ENETUNREACH); 444 (error == ENETUNREACH);
455 } 445 }
456 446
457 447
458 intptr_t ServerSocket::Accept(intptr_t fd) { 448 intptr_t ServerSocket::Accept(intptr_t fd) {
459 intptr_t socket; 449 intptr_t socket;
460 struct sockaddr clientaddr; 450 struct sockaddr clientaddr;
461 socklen_t addrlen = sizeof(clientaddr); 451 socklen_t addrlen = sizeof(clientaddr);
462 socket = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(accept(fd, &clientaddr, &addrlen)); 452 socket = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(accept4(
453 fd, &clientaddr, &addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC));
463 if (socket == -1) { 454 if (socket == -1) {
464 if (IsTemporaryAcceptError(errno)) { 455 if (IsTemporaryAcceptError(errno)) {
465 // We need to signal to the caller that this is actually not an 456 // We need to signal to the caller that this is actually not an
466 // error. We got woken up from the poll on the listening socket, 457 // error. We got woken up from the poll on the listening socket,
467 // but there is no connection ready to be accepted. 458 // but there is no connection ready to be accepted.
468 ASSERT(kTemporaryFailure != -1); 459 ASSERT(kTemporaryFailure != -1);
469 socket = kTemporaryFailure; 460 socket = kTemporaryFailure;
470 } 461 }
471 } else {
472 Socket::SetNonBlocking(socket);
473 } 462 }
474 return socket; 463 return socket;
475 } 464 }
476 465
477 466
478 void Socket::Close(intptr_t fd) { 467 void Socket::Close(intptr_t fd) {
479 ASSERT(fd >= 0); 468 ASSERT(fd >= 0);
480 int err = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd)); 469 int err = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd));
481 if (err != 0) { 470 if (err != 0) {
482 const int kBufferSize = 1024; 471 const int kBufferSize = 1024;
483 char error_buf[kBufferSize]; 472 char error_buf[kBufferSize];
484 Log::PrintErr("%s\n", strerror_r(errno, error_buf, kBufferSize)); 473 Log::PrintErr("%s\n", strerror_r(errno, error_buf, kBufferSize));
485 } 474 }
486 } 475 }
487 476
488 477
489 bool Socket::SetNonBlocking(intptr_t fd) {
490 return FDUtils::SetNonBlocking(fd);
491 }
492
493
494 bool Socket::SetBlocking(intptr_t fd) {
495 return FDUtils::SetBlocking(fd);
496 }
497
498
499 bool Socket::GetNoDelay(intptr_t fd, bool* enabled) { 478 bool Socket::GetNoDelay(intptr_t fd, bool* enabled) {
500 int on; 479 int on;
501 socklen_t len = sizeof(on); 480 socklen_t len = sizeof(on);
502 int err = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(getsockopt(fd, 481 int err = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(getsockopt(fd,
503 IPPROTO_TCP, 482 IPPROTO_TCP,
504 TCP_NODELAY, 483 TCP_NODELAY,
505 reinterpret_cast<void *>(&on), 484 reinterpret_cast<void *>(&on),
506 &len)); 485 &len));
507 if (err == 0) { 486 if (err == 0) {
508 *enabled = on == 1; 487 *enabled = on == 1;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 mreq.gr_interface = interfaceIndex; 605 mreq.gr_interface = interfaceIndex;
627 memmove(&mreq.gr_group, &addr->ss, SocketAddress::GetAddrLength(addr)); 606 memmove(&mreq.gr_group, &addr->ss, SocketAddress::GetAddrLength(addr));
628 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt( 607 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt(
629 fd, proto, MCAST_LEAVE_GROUP, &mreq, sizeof(mreq))) == 0; 608 fd, proto, MCAST_LEAVE_GROUP, &mreq, sizeof(mreq))) == 0;
630 } 609 }
631 610
632 } // namespace bin 611 } // namespace bin
633 } // namespace dart 612 } // namespace dart
634 613
635 #endif // defined(TARGET_OS_LINUX) 614 #endif // defined(TARGET_OS_LINUX)
OLDNEW
« no previous file with comments | « runtime/bin/socket.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698