Accurate NIO constraint level determination for IBM JDK 6

This commit is contained in:
Trustin Lee 2009-07-09 06:11:32 +00:00
parent 75688a719d
commit 0fa25a96a0

View File

@ -29,11 +29,14 @@ import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel; import java.nio.channels.ServerSocketChannel;
import java.nio.channels.spi.SelectorProvider; import java.nio.channels.spi.SelectorProvider;
import java.util.Set; import java.util.Set;
import java.util.Map.Entry;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jboss.netty.logging.InternalLogger; import org.jboss.netty.logging.InternalLogger;
import org.jboss.netty.logging.InternalLoggerFactory; import org.jboss.netty.logging.InternalLoggerFactory;
@ -57,8 +60,6 @@ class NioProviderMetadata {
private static final String CONSTRAINT_LEVEL_PROPERTY = private static final String CONSTRAINT_LEVEL_PROPERTY =
"java.nio.channels.spi.constraintLevel"; "java.nio.channels.spi.constraintLevel";
private static final long AUTODETECTION_TIMEOUT = 7000L;
/** /**
* 0 - no need to wake up to get / set interestOps (most cases) * 0 - no need to wake up to get / set interestOps (most cases)
* 1 - no need to wake up to get interestOps, but need to wake up to set. * 1 - no need to wake up to get interestOps, but need to wake up to set.
@ -87,26 +88,11 @@ class NioProviderMetadata {
if (constraintLevel < 0) { if (constraintLevel < 0) {
constraintLevel = detectConstraintLevelFromSystemProperties(); constraintLevel = detectConstraintLevelFromSystemProperties();
if (constraintLevel < 0) {
logger.debug(
"Couldn't get the NIO constraint level from the system properties.");
ConstraintLevelAutodetector autodetector =
new ConstraintLevelAutodetector();
try {
constraintLevel = autodetector.autodetectWithTimeout();
} catch (Exception e) {
// Probably because of security manager - try again without
// creating a new thread directly.
constraintLevel = autodetector.autodetectWithoutTimeout();
}
}
if (constraintLevel < 0) { if (constraintLevel < 0) {
constraintLevel = 2; constraintLevel = 2;
logger.warn( logger.debug(
"Failed to autodetect the NIO constraint level; " + "Couldn't determine the NIO constraint level from " +
"using the safest level (2)"); "the system properties; using the safest level (2)");
} else if (constraintLevel != 0) { } else if (constraintLevel != 0) {
logger.info( logger.info(
"Using the autodetected NIO constraint level: " + "Using the autodetected NIO constraint level: " +
@ -130,6 +116,7 @@ class NioProviderMetadata {
private static int detectConstraintLevelFromSystemProperties() { private static int detectConstraintLevelFromSystemProperties() {
String version = SystemPropertyUtil.get("java.specification.version"); String version = SystemPropertyUtil.get("java.specification.version");
String vminfo = SystemPropertyUtil.get("java.vm.info", "");
String os = SystemPropertyUtil.get("os.name"); String os = SystemPropertyUtil.get("os.name");
String vendor = SystemPropertyUtil.get("java.vm.vendor"); String vendor = SystemPropertyUtil.get("java.vm.vendor");
String provider; String provider;
@ -147,6 +134,12 @@ class NioProviderMetadata {
os = os.toLowerCase(); os = os.toLowerCase();
vendor = vendor.toLowerCase(); vendor = vendor.toLowerCase();
System.out.println(version);
System.out.println(vminfo);
System.out.println(os);
System.out.println(vendor);
System.out.println(provider);
// Sun JVM // Sun JVM
if (vendor.indexOf("sun") >= 0) { if (vendor.indexOf("sun") >= 0) {
// Linux // Linux
@ -178,41 +171,39 @@ class NioProviderMetadata {
} }
// IBM // IBM
} else if (vendor.indexOf("ibm") >= 0) { } else if (vendor.indexOf("ibm") >= 0) {
// Linux // Linux or AIX
if (os.indexOf("linux") >= 0) { if (os.indexOf("linux") >= 0 || os.indexOf("aix") >= 0) {
if (version.equals("1.5") || version.matches("^1\\.5\\D.*$")) { if (version.equals("1.5") || version.matches("^1\\.5\\D.*$")) {
if (provider.equals("sun.nio.ch.PollSelectorProvider")) { if (provider.equals("sun.nio.ch.PollSelectorProvider")) {
return 1; return 1;
} }
} } else if (version.equals("1.6") || version.matches("^1\\.6\\D.*$")) {
// IBM JDK 1.6 has different constraint level for different
// version. The exact version can be determined only by its
// build date.
Pattern datePattern = Pattern.compile(
"(?:^|[^0-9])(" +
"[2-9][0-9]{3}" + // year
"(?:0[1-9]|1[0-2])" + // month
"(?:0[1-9]|[12][0-9]|3[01])" + // day of month
")(?:$|[^0-9])");
// Commented out - the constraint level of IBM JDK 1.6 is Matcher dateMatcher = datePattern.matcher(vminfo);
// different between versions. if (dateMatcher.find()) {
// long dateValue = Long.parseLong(dateMatcher.group(1));
//else if (version.equals("1.6") || version.matches("^1\\.6\\D.*$")) { if (dateValue < 20081105L) {
// if (provider.equals("sun.nio.ch.EPollSelectorProvider") || // SR0, 1, and 2
// provider.equals("sun.nio.ch.PollSelectorProvider")) { return 2;
// return 2; } else {
// } // SR3 and later
//} if (provider.equals("sun.nio.ch.EPollSelectorProvider")) {
return 0;
// AIX } else if (provider.equals("sun.nio.ch.PollSelectorProvider")) {
} if (os.indexOf("aix") >= 0) {
if (version.equals("1.5") || version.matches("^1\\.5\\D.*$")) {
if (provider.equals("sun.nio.ch.PollSelectorProvider")) {
return 1; return 1;
} }
} }
}
// Commented out - the constraint level of IBM JDK 1.6 is }
// different between versions.
//
//else if (version.equals("1.6") || version.matches("^1\\.6\\D.*$")) {
// if (provider.equals("sun.nio.ch.EPollSelectorProvider") ||
// provider.equals("sun.nio.ch.PollSelectorProvider")) {
// return 2;
// }
//}
} }
// BEA // BEA
} else if (vendor.indexOf("bea") >= 0 || vendor.indexOf("oracle") >= 0) { } else if (vendor.indexOf("bea") >= 0 || vendor.indexOf("oracle") >= 0) {
@ -229,13 +220,17 @@ class NioProviderMetadata {
return 0; return 0;
} }
} }
// Apache Software Foundation
} else if (vendor.indexOf("apache") >= 0) {
if (provider.equals("org.apache.harmony.nio.internal.SelectorProviderImpl")) {
return 1;
}
} }
// Others (untested) // Others (untested)
return -1; return -1;
} }
private static final class ConstraintLevelAutodetector { private static final class ConstraintLevelAutodetector {
ConstraintLevelAutodetector() { ConstraintLevelAutodetector() {
@ -267,7 +262,7 @@ class NioProviderMetadata {
for (;;) { for (;;) {
try { try {
Integer result = resultQueue.poll(AUTODETECTION_TIMEOUT, TimeUnit.MILLISECONDS); Integer result = resultQueue.poll(10000, TimeUnit.MILLISECONDS);
if (result == null) { if (result == null) {
logger.warn("NIO constraint level autodetection timed out."); logger.warn("NIO constraint level autodetection timed out.");
return -1; return -1;
@ -473,4 +468,19 @@ class NioProviderMetadata {
} }
} }
} }
public static void main(String[] args) throws Exception {
for (Entry<Object, Object> e: System.getProperties().entrySet()) {
System.out.println(e.getKey() + ": " + e.getValue());
}
System.out.println();
System.out.println("Hard-coded Constraint Level: " + CONSTRAINT_LEVEL);
System.out.println(
"Auto-detected Constraint Level: " +
new ConstraintLevelAutodetector().autodetectWithoutTimeout());
}
private NioProviderMetadata() {
// Unused
}
} }