Chromium Code Reviews| Index: net/udp/udp_socket_libevent.cc |
| diff --git a/net/udp/udp_socket_libevent.cc b/net/udp/udp_socket_libevent.cc |
| index a6c1b72b50ac651c8a711c568c042e0d9ddcd504..c7f288d2c68a7f6758515834505f0d24e6240e21 100644 |
| --- a/net/udp/udp_socket_libevent.cc |
| +++ b/net/udp/udp_socket_libevent.cc |
| @@ -6,8 +6,8 @@ |
| #include <errno.h> |
| #include <fcntl.h> |
| -#include <netdb.h> |
| #include <net/if.h> |
| +#include <netdb.h> |
| #include <netinet/in.h> |
| #include <sys/ioctl.h> |
| #include <sys/socket.h> |
| @@ -56,6 +56,25 @@ int GetIPv4AddressFromIndex(int socket, uint32 index, uint32* address){ |
| return OK; |
| } |
| +// On OSX the file descriptor is guarded to detect the cause of |
| +// crbug.com/461246. sys/guarded.h is not included in the SDK, so the API needs |
| +// to be defined here. |
|
Mark Mentovai
2015/04/02 14:37:06
Drive the point home by saying in the comment that
Sergey Ulanov
2015/04/02 18:05:42
Added TODO to remove it.
|
| + |
| +typedef uint64_t guardid_t; |
| + |
| +int guarded_close_np(int fd, const guardid_t *guard) { |
| + return syscall(442, fd, guard); |
|
Mark Mentovai
2015/04/02 14:37:06
This is only available in 10.9 and 10.10. It’ll be
Sergey Ulanov
2015/04/02 18:05:42
Done.
|
| +} |
| +int change_fdguard_np(int fd, const guardid_t *guard, u_int flags, |
| + const guardid_t *nguard, u_int nflags, int *fdflagsp) { |
| + return syscall(444, fd, guard, flags, nguard, nflags, fdflagsp); |
| +} |
| + |
| +const unsigned int GUARD_CLOSE = 1u<<0; |
| +const unsigned int GUARD_DUP = 1u<<1; |
| + |
| +const guardid_t kSocketFdGuard = 0xD712BC0BC9A4EAD4; |
| + |
| #endif // OS_MACOSX |
| } // namespace |
| @@ -98,6 +117,10 @@ int UDPSocketLibevent::Open(AddressFamily address_family) { |
| socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, 0); |
| if (socket_ == kInvalidSocket) |
| return MapSystemError(errno); |
| +#if defined(OS_MACOSX) |
| + PCHECK(change_fdguard_np(socket_, NULL, 0, &kSocketFdGuard, |
| + GUARD_CLOSE | GUARD_DUP, NULL) == 0); |
| +#endif // OS_MACOSX |
| if (SetNonBlocking(socket_)) { |
| const int err = MapSystemError(errno); |
| Close(); |
| @@ -127,7 +150,11 @@ void UDPSocketLibevent::Close() { |
| ok = write_socket_watcher_.StopWatchingFileDescriptor(); |
| DCHECK(ok); |
| +#if defined(OS_MACOSX) |
| + PCHECK(IGNORE_EINTR(guarded_close_np(socket_, &kSocketFdGuard)) == 0); |
| +#else |
| PCHECK(IGNORE_EINTR(close(socket_)) == 0); |
| +#endif // OS_MACOSX |
| socket_ = kInvalidSocket; |
| addr_family_ = 0; |