$OpenBSD: patch-jdk_src_solaris_native_java_net_bsd_close_c,v 1.3 2013/02/02 17:39:23 kurt Exp $
--- jdk/src/solaris/native/java/net/bsd_close.c.orig	Tue Aug 28 19:15:27 2012
+++ jdk/src/solaris/native/java/net/bsd_close.c	Fri Feb  1 13:06:28 2013
@@ -345,7 +345,77 @@ int NET_Select(int s, fd_set *readfds, fd_set *writefd
  * signal other than our wakeup signal.
  */
 int NET_Timeout(int s, long timeout) {
+/*
+ * On MacOS X, poll(2) is not working correctly, so a select(2) based
+ * implementation is preferred.  See
+ *
+ * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7131399
+ *
+ * However, on FreeBSD, the select(2) based implementation can cause
+ * crashes under load and poll(2) is preferred.  See
+ *
+ * http://docs.freebsd.org/cgi/getmsg.cgi?fetch=215525+0+current/freebsd-java
+ *
+ * Other *BSD should adjust as appropriate.
+ */
+#ifndef __APPLE__
     long prevtime = 0, newtime;
+    struct timeval t;
+    fdEntry_t *fdEntry = getFdEntry(s);
+
+    /*
+     * Check that fd hasn't been closed.
+     */
+    if (fdEntry == NULL) {
+        errno = EBADF;
+        return -1;
+    }
+
+    /*
+     * Pick up current time as may need to adjust timeout
+     */
+    if (timeout > 0) {
+        gettimeofday(&t, NULL);
+        prevtime = t.tv_sec * 1000  +  t.tv_usec / 1000;
+    }
+
+    for(;;) {
+        struct pollfd pfd;
+        int rv;
+        threadEntry_t self;
+
+        /*
+         * Poll the fd. If interrupted by our wakeup signal
+         * errno will be set to EBADF.
+         */
+        pfd.fd = s;
+        pfd.events = POLLIN | POLLERR;
+
+        startOp(fdEntry, &self);
+        rv = poll(&pfd, 1, timeout);
+        endOp(fdEntry, &self);
+
+        /*
+         * If interrupted then adjust timeout. If timeout
+         * has expired return 0 (indicating timeout expired).
+         */
+        if (rv < 0 && errno == EINTR) {
+            if (timeout > 0) {
+                gettimeofday(&t, NULL);
+                newtime = t.tv_sec * 1000  +  t.tv_usec / 1000;
+                timeout -= newtime - prevtime;
+                if (timeout <= 0) {
+                    return 0;
+                }
+                prevtime = newtime;
+            }
+        } else {
+            return rv;
+        }
+
+    }
+#else
+    long prevtime = 0, newtime;
     struct timeval t, *tp = &t;
     fdEntry_t *fdEntry = getFdEntry(s);
 
@@ -414,4 +484,5 @@ int NET_Timeout(int s, long timeout) {
         }
 
     }
+#endif
 }
