Propagate full Unsafe unavailability reason in PlatformDependent

Motivation:
It is not clear why Unsafe is unavailable when it is explicitly
disabled, or when Netty thinks it is running on Android.

Modification:
Change the "has" fields and methods to be causes.  A null cause
means Unsafe is present.  This catches all possible reason why
Unsafe might not be available.

Result:
Easier to debug Netty start up when logging cannot be turned on.
This commit is contained in:
Carl Mastrangelo 2018-02-16 10:43:06 -08:00 committed by Scott Mitchell
parent 268b901844
commit 15560530d4
2 changed files with 24 additions and 24 deletions

View File

@ -78,9 +78,9 @@ public final class PlatformDependent {
private static final boolean CAN_ENABLE_TCP_NODELAY_BY_DEFAULT = !isAndroid();
private static final boolean HAS_UNSAFE = hasUnsafe0();
private static final Throwable UNSAFE_UNAVAILABILITY_CAUSE = unsafeUnavailabilityCause0();
private static final boolean DIRECT_BUFFER_PREFERRED =
HAS_UNSAFE && !SystemPropertyUtil.getBoolean("io.netty.noPreferDirect", false);
UNSAFE_UNAVAILABILITY_CAUSE == null && !SystemPropertyUtil.getBoolean("io.netty.noPreferDirect", false);
private static final long MAX_DIRECT_MEMORY = maxDirectMemory0();
private static final int MPSC_CHUNK_SIZE = 1024;
@ -249,14 +249,14 @@ public final class PlatformDependent {
* direct memory access.
*/
public static boolean hasUnsafe() {
return HAS_UNSAFE;
return UNSAFE_UNAVAILABILITY_CAUSE == null;
}
/**
* Return the reason (if any) why {@code sun.misc.Unsafe} was not available.
*/
public static Throwable getUnsafeUnavailabilityCause() {
return PlatformDependent0.getUnsafeUnavailabilityCause();
return UNSAFE_UNAVAILABILITY_CAUSE;
}
/**
@ -965,24 +965,24 @@ public final class PlatformDependent {
return "root".equals(username) || "toor".equals(username);
}
private static boolean hasUnsafe0() {
private static Throwable unsafeUnavailabilityCause0() {
if (isAndroid()) {
logger.debug("sun.misc.Unsafe: unavailable (Android)");
return false;
return new UnsupportedOperationException("sun.misc.Unsafe: unavailable (Android)");
}
if (PlatformDependent0.isExplicitNoUnsafe()) {
return false;
Throwable cause = PlatformDependent0.getUnsafeUnavailabilityCause();
if (cause != null) {
return cause;
}
try {
boolean hasUnsafe = PlatformDependent0.hasUnsafe();
logger.debug("sun.misc.Unsafe: {}", hasUnsafe ? "available" : "unavailable");
return hasUnsafe;
return hasUnsafe ? null : PlatformDependent0.getUnsafeUnavailabilityCause();
} catch (Throwable t) {
logger.trace("Could not determine if Unsafe is available", t);
// Probably failed to initialize PlatformDependent0.
return false;
return new UnsupportedOperationException("Could not determine if Unsafe is available", t);
}
}

View File

@ -39,7 +39,7 @@ final class PlatformDependent0 {
private static final long ADDRESS_FIELD_OFFSET;
private static final long BYTE_ARRAY_BASE_OFFSET;
private static final Constructor<?> DIRECT_BUFFER_CONSTRUCTOR;
private static final boolean IS_EXPLICIT_NO_UNSAFE = explicitNoUnsafe0();
private static final Throwable EXPLICIT_NO_UNSAFE_CAUSE = explicitNoUnsafeCause0();
private static final Method ALLOCATE_ARRAY_METHOD;
private static final int JAVA_VERSION = javaVersion0();
private static final boolean IS_ANDROID = isAndroid0();
@ -71,10 +71,9 @@ final class PlatformDependent0 {
Unsafe unsafe;
Object internalUnsafe = null;
if (isExplicitNoUnsafe()) {
if ((unsafeUnavailabilityCause = EXPLICIT_NO_UNSAFE_CAUSE) != null) {
direct = null;
addressField = null;
unsafeUnavailabilityCause = new UnsupportedOperationException("Unsafe explicitly disabled");
unsafe = null;
internalUnsafe = null;
} else {
@ -369,32 +368,33 @@ final class PlatformDependent0 {
}
static boolean isExplicitNoUnsafe() {
return IS_EXPLICIT_NO_UNSAFE;
return EXPLICIT_NO_UNSAFE_CAUSE == null;
}
private static boolean explicitNoUnsafe0() {
private static Throwable explicitNoUnsafeCause0() {
final boolean noUnsafe = SystemPropertyUtil.getBoolean("io.netty.noUnsafe", false);
logger.debug("-Dio.netty.noUnsafe: {}", noUnsafe);
if (noUnsafe) {
logger.debug("sun.misc.Unsafe: unavailable (io.netty.noUnsafe)");
return true;
return new UnsupportedOperationException("sun.misc.Unsafe: unavailable (io.netty.noUnsafe)");
}
// Legacy properties
boolean tryUnsafe;
String unsafePropName;
if (SystemPropertyUtil.contains("io.netty.tryUnsafe")) {
tryUnsafe = SystemPropertyUtil.getBoolean("io.netty.tryUnsafe", true);
unsafePropName = "io.netty.tryUnsafe";
} else {
tryUnsafe = SystemPropertyUtil.getBoolean("org.jboss.netty.tryUnsafe", true);
unsafePropName = "org.jboss.netty.tryUnsafe";
}
if (!tryUnsafe) {
logger.debug("sun.misc.Unsafe: unavailable (io.netty.tryUnsafe/org.jboss.netty.tryUnsafe)");
return true;
if (!SystemPropertyUtil.getBoolean(unsafePropName, true)) {
String msg = "sun.misc.Unsafe: unavailable (" + unsafePropName + ")";
logger.debug(msg);
return new UnsupportedOperationException(msg);
}
return false;
return null;
}
static boolean isUnaligned() {