$OpenBSD: patch-hotspot_src_os_bsd_vm_hpi_bsd_hpp,v 1.1.1.1 2007/05/08 17:06:19 kurt Exp $
--- hotspot/src/os/bsd/vm/hpi_bsd.hpp.orig	Mon Apr 16 08:42:36 2007
+++ hotspot/src/os/bsd/vm/hpi_bsd.hpp	Mon Apr 16 08:42:38 2007
@@ -39,26 +39,22 @@
 // HPI_FileInterface
 
 inline int hpi::close(int fd) {
-  return ::close(fd);
+  RESTARTABLE_RETURN_INT(::close(fd)); 
 }
 
 inline size_t hpi::read(int fd, void *buf, unsigned int nBytes) {
-  size_t res;
-  RESTARTABLE( (size_t) ::read(fd, buf, (size_t) nBytes), res);
-  return res;
+  INTERRUPTIBLE_RETURN_INT(::read(fd, buf, (size_t) nBytes), os::Bsd::clear_interrupted);
 }
 
 inline size_t hpi::write(int fd, const void *buf, unsigned int nBytes) {
-  size_t res;
-  RESTARTABLE((size_t) ::write(fd, buf, (size_t) nBytes), res);
-  return res;
+  INTERRUPTIBLE_RETURN_INT(::write(fd, buf, (size_t) nBytes), os::Bsd::clear_interrupted);
 }
 
 
 // HPI_SocketInterface
 
 inline int hpi::socket_close(int fd) {
-  return ::close(fd);
+  RESTARTABLE_RETURN_INT(::close(fd));
 }
 
 inline int hpi::socket(int domain, int type, int protocol) {
@@ -66,11 +62,11 @@ inline int hpi::socket(int domain, int type, int proto
 }
 
 inline int hpi::recv(int fd, char *buf, int nBytes, int flags) {
-  RESTARTABLE_RETURN_INT(::recv(fd, buf, nBytes, (unsigned int) flags));
+  INTERRUPTIBLE_RETURN_INT(::recv(fd, buf, nBytes, (unsigned int) flags), os::Bsd::clear_interrupted);
 }
 
 inline int hpi::send(int fd, char *buf, int nBytes, int flags) {
-  RESTARTABLE_RETURN_INT(::send(fd, buf, nBytes, (unsigned int) flags));
+  INTERRUPTIBLE_RETURN_INT(::send(fd, buf, nBytes, (unsigned int) flags), os::Bsd::clear_interrupted);
 }
 
 inline int hpi::timeout(int fd, long timeout) {
@@ -81,13 +77,13 @@ inline int hpi::timeout(int fd, long timeout) {
   prevtime = ((julong)t.tv_sec * 1000)  +  t.tv_usec / 1000;
 
   for(;;) {
+    int res;
     struct pollfd pfd;
 
     pfd.fd = fd;
     pfd.events = POLLIN | POLLERR;
   
-    int res = ::poll(&pfd, 1, timeout);
-
+    INTERRUPTIBLE_NORESTART(::poll(&pfd, 1, timeout), res, os::Bsd::clear_interrupted);
     if (res == OS_ERR && errno == EINTR) {
 
       // On Bsd any value < 0 means "forever"
@@ -110,7 +106,26 @@ inline int hpi::listen(int fd, int count) {
 }
 
 inline int hpi::connect(int fd, struct sockaddr *him, int len) {
-  RESTARTABLE_RETURN_INT(::connect(fd, him, len));
+  do {
+    int _result;
+    INTERRUPTIBLE_NORESTART(::connect(fd, him, len), _result,
+			    os::Bsd::clear_interrupted);
+
+    // Depending on when thread interruption is reset, _result could be
+    // one of two values when errno == EINTR
+
+    if (((_result == OS_INTRPT) || (_result == OS_ERR)) && (errno == EINTR)) {
+      /* restarting a connect() changes its errno semantics */
+      INTERRUPTIBLE(::connect(fd, him, len), _result,
+		      os::Bsd::clear_interrupted);
+      /* undo these changes */
+      if (_result == OS_ERR) {
+	if (errno == EALREADY) errno = EINPROGRESS; /* fall through */
+	else if (errno == EISCONN) { errno = 0; return OS_OK; }
+      }
+    }
+    return _result;
+  } while(false);
 }
 
 inline int hpi::accept(int fd, struct sockaddr *him, int *len) {
@@ -121,26 +136,33 @@ inline int hpi::accept(int fd, struct sockaddr *him, i
   // to 64 bits on some platform that we support.
   // Bsd doc says this can't return EINTR, unlike accept() on Solaris
 
-  return ::accept(fd, him, (socklen_t *)len);
+  if (fd < 0)
+    return OS_ERR;
+  INTERRUPTIBLE_RETURN_INT((int)::accept(fd, him, (socklen_t*) len), os::Bsd::clear_interrupted); 
 }
 
 inline int hpi::recvfrom(int fd, char *buf, int nBytes, int flags,
 		         sockaddr *from, int *fromlen) {
-  RESTARTABLE_RETURN_INT(::recvfrom(fd, buf, nBytes, (unsigned int) flags, from, (socklen_t *)fromlen));
+  INTERRUPTIBLE_RETURN_INT((int)::recvfrom(fd, buf, nBytes, (unsigned int) flags, from, (socklen_t *)fromlen), os::Bsd::clear_interrupted);
 }
 
 inline int hpi::sendto(int fd, char *buf, int len, int flags,
 			struct sockaddr *to, int tolen) {
-  RESTARTABLE_RETURN_INT(::sendto(fd, buf, len, (unsigned int) flags, to, tolen));
+  INTERRUPTIBLE_RETURN_INT((int)::sendto(fd, buf, len, (unsigned int) flags, to, tolen),os::Bsd::clear_interrupted);
 }
 
 inline int hpi::socket_available(int fd, jint *pbytes) {
-  // Bsd doc says EINTR not returned, unlike Solaris
-  int ret = ::ioctl(fd, FIONREAD, pbytes);
+  if (fd < 0)
+    return OS_OK;
 
+  int ret;
+
+  RESTARTABLE(::ioctl(fd, FIONREAD, pbytes), ret);
+
   //%% note ioctl can return 0 when successful, JVM_SocketAvailable
   // is expected to return 0 on failure and 1 on success to the jdk.
-  return (ret < 0) ? 0 : 1;
+
+  return (ret == OS_ERR) ? 0 : 1;
 }
 
 
@@ -167,7 +189,7 @@ HPIDECL(bind, "bind", _socket, Bind, 
         (fd, him, len));
 */
 inline int hpi::bind(int fd, struct sockaddr *him, int len){
-  return ::bind(fd, him, len);
+  INTERRUPTIBLE_RETURN_INT_NORESTART(::bind(fd, him, len),os::Bsd::clear_interrupted);
 }
 
 /*
