From 879b239e414a017dedcd8fff48092ec966358ed8 Mon Sep 17 00:00:00 2001 From: Jonathan Lu Date: Sat, 7 Jun 2014 00:17:02 +0800 Subject: [PATCH] 8043954: Add async connect() support to NET_Connect() for AIX platform Reviewed-by: alanb --- jdk/src/aix/native/java/net/aix_close.c | 52 ++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/jdk/src/aix/native/java/net/aix_close.c b/jdk/src/aix/native/java/net/aix_close.c index 148e05da0c8..0165c9a1959 100644 --- a/jdk/src/aix/native/java/net/aix_close.c +++ b/jdk/src/aix/native/java/net/aix_close.c @@ -370,7 +370,57 @@ int NET_Accept(int s, struct sockaddr *addr, int *addrlen) { } int NET_Connect(int s, struct sockaddr *addr, int addrlen) { - BLOCKING_IO_RETURN_INT( s, connect(s, addr, addrlen) ); + int crc = -1, prc = -1; + threadEntry_t self; + fdEntry_t* fdEntry = getFdEntry(s); + + if (fdEntry == NULL) { + errno = EBADF; + return -1; + } + + /* On AIX, when the system call connect() is interrupted, the connection + * is not aborted and it will be established asynchronously by the kernel. + * Hence, no need to restart connect() when EINTR is received + */ + startOp(fdEntry, &self); + crc = connect(s, addr, addrlen); + endOp(fdEntry, &self); + + if (crc == -1 && errno == EINTR) { + struct pollfd s_pollfd; + int sockopt_arg = 0; + socklen_t len; + + s_pollfd.fd = s; + s_pollfd.events = POLLOUT | POLLERR; + + /* poll the file descriptor */ + do { + startOp(fdEntry, &self); + prc = poll(&s_pollfd, 1, -1); + endOp(fdEntry, &self); + } while (prc == -1 && errno == EINTR); + + if (prc < 0) + return prc; + + len = sizeof(sockopt_arg); + + /* Check whether the connection has been established */ + if (getsockopt(s, SOL_SOCKET, SO_ERROR, &sockopt_arg, &len) == -1) + return -1; + + if (sockopt_arg != 0 ) { + errno = sockopt_arg; + return -1; + } + } else { + return crc; + } + + /* At this point, fd is connected. Set successful return code */ + return 0; } int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {