Index: runtime/bin/socket_fuchsia.cc |
diff --git a/runtime/bin/socket_fuchsia.cc b/runtime/bin/socket_fuchsia.cc |
index ba6f51f0c3b3d576d842f4ae64e19e8e2fda53ab..f8c138fd4703cc5e5d00390cfead29e01a99de8d 100644 |
--- a/runtime/bin/socket_fuchsia.cc |
+++ b/runtime/bin/socket_fuchsia.cc |
@@ -11,6 +11,7 @@ |
#include <errno.h> // NOLINT |
+#include "bin/eventhandler.h" |
#include "bin/fdutils.h" |
#include "platform/signal_blocker.h" |
@@ -46,6 +47,10 @@ Socket::Socket(intptr_t fd) |
void Socket::SetClosedFd() { |
+ ASSERT(fd_ != kClosedFd); |
+ IOHandle* handle = reinterpret_cast<IOHandle*>(fd_); |
+ ASSERT(handle != NULL); |
+ handle->Release(); |
fd_ = kClosedFd; |
} |
@@ -63,19 +68,22 @@ static intptr_t Create(const RawAddr& addr) { |
FDUtils::SaveErrorAndClose(fd); |
return -1; |
} |
- return fd; |
+ IOHandle* io_handle = new IOHandle(fd); |
+ return reinterpret_cast<intptr_t>(io_handle); |
} |
static intptr_t Connect(intptr_t fd, const RawAddr& addr) { |
- LOG_INFO("Connect: calling connect(%ld)\n", fd); |
+ IOHandle* handle = reinterpret_cast<IOHandle*>(fd); |
+ LOG_INFO("Connect: calling connect(%ld)\n", handle->fd()); |
intptr_t result = NO_RETRY_EXPECTED( |
- connect(fd, &addr.addr, SocketAddress::GetAddrLength(addr))); |
+ connect(handle->fd(), &addr.addr, SocketAddress::GetAddrLength(addr))); |
if ((result == 0) || (errno == EINPROGRESS)) { |
- return fd; |
+ return reinterpret_cast<intptr_t>(handle); |
} |
- LOG_ERR("Connect: connect(%ld) failed\n", fd); |
- FDUtils::SaveErrorAndClose(fd); |
+ LOG_ERR("Connect: connect(%ld) failed\n", handle->fd()); |
+ FDUtils::SaveErrorAndClose(handle->fd()); |
+ handle->Release(); |
return -1; |
} |
@@ -85,9 +93,12 @@ intptr_t Socket::CreateConnect(const RawAddr& addr) { |
if (fd < 0) { |
return fd; |
} |
- if (!FDUtils::SetNonBlocking(fd)) { |
- LOG_ERR("CreateConnect: FDUtils::SetNonBlocking(%ld) failed\n", fd); |
- FDUtils::SaveErrorAndClose(fd); |
+ IOHandle* handle = reinterpret_cast<IOHandle*>(fd); |
+ if (!FDUtils::SetNonBlocking(handle->fd())) { |
+ LOG_ERR("CreateConnect: FDUtils::SetNonBlocking(%ld) failed\n", |
+ handle->fd()); |
+ FDUtils::SaveErrorAndClose(handle->fd()); |
+ handle->Release(); |
return -1; |
} |
return Connect(fd, addr); |
@@ -147,13 +158,16 @@ intptr_t ServerSocket::CreateBindListen(const RawAddr& addr, |
} |
LOG_INFO("ServerSocket::CreateBindListen: bind(%ld) succeeded\n", fd); |
+ IOHandle* io_handle = new IOHandle(fd); |
+ |
// Test for invalid socket port 65535 (some browsers disallow it). |
if ((SocketAddress::GetAddrPort(addr) == 0) && |
- (SocketBase::GetPort(fd) == 65535)) { |
+ (SocketBase::GetPort(reinterpret_cast<intptr_t>(io_handle)) == 65535)) { |
// Don't close the socket until we have created a new socket, ensuring |
// that we do not get the bad port number again. |
intptr_t new_fd = CreateBindListen(addr, backlog, v6_only); |
FDUtils::SaveErrorAndClose(fd); |
+ io_handle->Release(); |
return new_fd; |
} |
@@ -161,6 +175,7 @@ intptr_t ServerSocket::CreateBindListen(const RawAddr& addr, |
if (NO_RETRY_EXPECTED(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) { |
LOG_ERR("ServerSocket::CreateBindListen: listen failed(%ld)\n", fd); |
FDUtils::SaveErrorAndClose(fd); |
+ io_handle->Release(); |
return -1; |
} |
LOG_INFO("ServerSocket::CreateBindListen: listen(%ld) succeeded\n", fd); |
@@ -168,9 +183,10 @@ intptr_t ServerSocket::CreateBindListen(const RawAddr& addr, |
if (!FDUtils::SetNonBlocking(fd)) { |
LOG_ERR("CreateBindListen: FDUtils::SetNonBlocking(%ld) failed\n", fd); |
FDUtils::SaveErrorAndClose(fd); |
+ io_handle->Release(); |
return -1; |
} |
- return fd; |
+ return reinterpret_cast<intptr_t>(io_handle); |
} |
@@ -191,11 +207,12 @@ static bool IsTemporaryAcceptError(int error) { |
intptr_t ServerSocket::Accept(intptr_t fd) { |
+ IOHandle* listen_handle = reinterpret_cast<IOHandle*>(fd); |
intptr_t socket; |
struct sockaddr clientaddr; |
socklen_t addrlen = sizeof(clientaddr); |
- LOG_INFO("ServerSocket::Accept: calling accept(%ld)\n", fd); |
- socket = NO_RETRY_EXPECTED(accept(fd, &clientaddr, &addrlen)); |
+ LOG_INFO("ServerSocket::Accept: calling accept(%ld)\n", listen_fd); |
+ socket = listen_handle->Accept(&clientaddr, &addrlen); |
if (socket == -1) { |
if (IsTemporaryAcceptError(errno)) { |
// We need to signal to the caller that this is actually not an |
@@ -204,20 +221,25 @@ intptr_t ServerSocket::Accept(intptr_t fd) { |
ASSERT(kTemporaryFailure != -1); |
socket = kTemporaryFailure; |
} else { |
- LOG_ERR("ServerSocket::Accept: accept(%ld) failed\n", fd); |
+ LOG_ERR("ServerSocket::Accept: accept(%ld) failed\n", listen_fd); |
} |
} else { |
- LOG_INFO("ServerSocket::Accept: accept(%ld) -> socket %ld\n", fd, socket); |
+ IOHandle* io_handle = new IOHandle(socket); |
+ LOG_INFO("ServerSocket::Accept: accept(%ld) -> socket %ld\n", listen_fd, |
+ socket); |
if (!FDUtils::SetCloseOnExec(socket)) { |
LOG_ERR("FDUtils::SetCloseOnExec(%ld) failed\n", socket); |
FDUtils::SaveErrorAndClose(socket); |
+ io_handle->Release(); |
return -1; |
} |
if (!FDUtils::SetNonBlocking(socket)) { |
LOG_ERR("FDUtils::SetNonBlocking(%ld) failed\n", socket); |
FDUtils::SaveErrorAndClose(socket); |
+ io_handle->Release(); |
return -1; |
} |
+ socket = reinterpret_cast<intptr_t>(io_handle); |
} |
return socket; |
} |