. Fix a crash under heavy network load by reverting to using poll(2) rather

than select(2).

PR:		175417
Based on the patch by:	Phil Phillips <pphillips@experts-exchange.com>
This commit is contained in:
Greg Lewis 2013-01-29 05:06:46 +00:00
parent 08e38ec2c5
commit e2304463d3
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=311149
2 changed files with 86 additions and 0 deletions

View File

@ -7,6 +7,7 @@
PORTNAME= openjdk
PORTVERSION= ${JDK_MAJOR_VERSION}.${PORT_MINOR_VERSION}.${PORT_BUILD_NUMBER}
PORTREVISION= 1
CATEGORIES= java devel
MASTER_SITES= http://download.java.net/openjdk/jdk${JDK_MAJOR_VERSION}u${JDK_MINOR_VERSION}/promoted/b${JDK_BUILD_NUMBER}/ \
http://download.java.net/jaxp/1.4.5/:jaxp \

View File

@ -0,0 +1,85 @@
--- jdk/src/solaris/native/java/net/bsd_close.c Wed Jan 16 16:04:50 2013 -0800
+++ jdk/src/solaris/native/java/net/bsd_close.c Thu Jan 17 22:14:02 2013 -0800
@@ -345,6 +345,76 @@
* 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.
+ */
+#ifdef __FreeBSD__
+ 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 @@
}
}
+#endif
}