Replace and merge DetectionUtil and DirectByteBufUtil into PlatformDependent and PlatformDependent0

PlatformDependent delegates the operations requires sun.misc.* to PlatformDependent0 to avoid runtime errors due to missing sun.misc.* classes.
This commit is contained in:
Trustin Lee 2013-01-11 14:03:27 +09:00
parent 5b5b39a606
commit 64ae8b6a37
17 changed files with 285 additions and 251 deletions

View File

@ -15,7 +15,7 @@
*/ */
package io.netty.buffer; package io.netty.buffer;
import io.netty.util.internal.DetectionUtil; import io.netty.util.internal.PlatformDependent;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -699,7 +699,7 @@ public class DefaultCompositeByteBuf extends AbstractByteBuf implements Composit
@Override @Override
public int getBytes(int index, GatheringByteChannel out, int length) public int getBytes(int index, GatheringByteChannel out, int length)
throws IOException { throws IOException {
if (DetectionUtil.javaVersion() < 7) { if (PlatformDependent.javaVersion() < 7) {
// XXX Gathering write is not supported because of a known issue. // XXX Gathering write is not supported because of a known issue.
// See http://bugs.sun.com/view_bug.do?bug_id=6210541 // See http://bugs.sun.com/view_bug.do?bug_id=6210541
return out.write(copiedNioBuffer(index, length)); return out.write(copiedNioBuffer(index, length));

View File

@ -16,6 +16,7 @@
package io.netty.buffer; package io.netty.buffer;
import io.netty.util.internal.PlatformDependent;
import io.netty.util.internal.StringUtil; import io.netty.util.internal.StringUtil;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -370,7 +371,7 @@ abstract class PoolArena<T> {
@Override @Override
protected void destroyChunk(PoolChunk<ByteBuffer> chunk) { protected void destroyChunk(PoolChunk<ByteBuffer> chunk) {
UnpooledDirectByteBuf.freeDirect(chunk.memory); PlatformDependent.freeDirectBuffer(chunk.memory);
} }
@Override @Override

View File

@ -15,7 +15,7 @@
*/ */
package io.netty.buffer; package io.netty.buffer;
import io.netty.util.internal.DetectionUtil; import io.netty.util.internal.PlatformDependent;
/** /**
* Simplistic {@link ByteBufAllocator} implementation that does not pool anything. * Simplistic {@link ByteBufAllocator} implementation that does not pool anything.
@ -41,7 +41,7 @@ public final class UnpooledByteBufAllocator extends AbstractByteBufAllocator {
@Override @Override
public ByteBuf ioBuffer() { public ByteBuf ioBuffer() {
if (DetectionUtil.canFreeDirectBuffer()) { if (PlatformDependent.canFreeDirectBuffer()) {
return directBuffer(0); return directBuffer(0);
} }

View File

@ -15,8 +15,7 @@
*/ */
package io.netty.buffer; package io.netty.buffer;
import io.netty.util.internal.DetectionUtil; import io.netty.util.internal.PlatformDependent;
import io.netty.util.internal.DirectByteBufUtil;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -109,7 +108,7 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
doNotFree = false; doNotFree = false;
} else { } else {
if (suspendedDeallocations == null) { if (suspendedDeallocations == null) {
freeDirect(oldBuffer); PlatformDependent.freeDirectBuffer(oldBuffer);
} else { } else {
suspendedDeallocations.add(oldBuffer); suspendedDeallocations.add(oldBuffer);
} }
@ -471,7 +470,7 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
} }
resumeIntermediaryDeallocations(); resumeIntermediaryDeallocations();
freeDirect(buffer); PlatformDependent.freeDirectBuffer(buffer);
} }
@Override @Override
@ -492,7 +491,7 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
this.suspendedDeallocations = null; this.suspendedDeallocations = null;
for (ByteBuffer buf: suspendedDeallocations) { for (ByteBuffer buf: suspendedDeallocations) {
freeDirect(buf); PlatformDependent.freeDirectBuffer(buf);
} }
return this; return this;
} }
@ -501,10 +500,4 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
public ByteBuf unwrap() { public ByteBuf unwrap() {
return null; return null;
} }
static void freeDirect(ByteBuffer buffer) {
if (DetectionUtil.canFreeDirectBuffer()) {
DirectByteBufUtil.freeDirect(buffer);
}
}
} }

View File

@ -16,14 +16,14 @@
package io.netty.handler.codec.spdy; package io.netty.handler.codec.spdy;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.util.internal.DetectionUtil; import io.netty.util.internal.PlatformDependent;
abstract class SpdyHeaderBlockCompressor { abstract class SpdyHeaderBlockCompressor {
static SpdyHeaderBlockCompressor newInstance( static SpdyHeaderBlockCompressor newInstance(
int version, int compressionLevel, int windowBits, int memLevel) { int version, int compressionLevel, int windowBits, int memLevel) {
if (DetectionUtil.javaVersion() >= 7) { if (PlatformDependent.javaVersion() >= 7) {
return new SpdyHeaderBlockZlibCompressor( return new SpdyHeaderBlockZlibCompressor(
version, compressionLevel); version, compressionLevel);
} else { } else {

View File

@ -15,7 +15,7 @@
*/ */
package io.netty.handler.codec.compression; package io.netty.handler.codec.compression;
import io.netty.util.internal.DetectionUtil; import io.netty.util.internal.PlatformDependent;
/** /**
* Creates a new {@link ZlibEncoder} and a new {@link ZlibDecoder}. * Creates a new {@link ZlibEncoder} and a new {@link ZlibDecoder}.
@ -23,7 +23,7 @@ import io.netty.util.internal.DetectionUtil;
public final class ZlibCodecFactory { public final class ZlibCodecFactory {
public static ZlibEncoder newZlibEncoder(int compressionLevel) { public static ZlibEncoder newZlibEncoder(int compressionLevel) {
if (DetectionUtil.javaVersion() < 7) { if (PlatformDependent.javaVersion() < 7) {
return new JZlibEncoder(compressionLevel); return new JZlibEncoder(compressionLevel);
} else { } else {
return new JdkZlibEncoder(compressionLevel); return new JdkZlibEncoder(compressionLevel);
@ -31,7 +31,7 @@ public final class ZlibCodecFactory {
} }
public static ZlibEncoder newZlibEncoder(ZlibWrapper wrapper) { public static ZlibEncoder newZlibEncoder(ZlibWrapper wrapper) {
if (DetectionUtil.javaVersion() < 7) { if (PlatformDependent.javaVersion() < 7) {
return new JZlibEncoder(wrapper); return new JZlibEncoder(wrapper);
} else { } else {
return new JdkZlibEncoder(wrapper); return new JdkZlibEncoder(wrapper);
@ -39,7 +39,7 @@ public final class ZlibCodecFactory {
} }
public static ZlibEncoder newZlibEncoder(ZlibWrapper wrapper, int compressionLevel) { public static ZlibEncoder newZlibEncoder(ZlibWrapper wrapper, int compressionLevel) {
if (DetectionUtil.javaVersion() < 7) { if (PlatformDependent.javaVersion() < 7) {
return new JZlibEncoder(wrapper, compressionLevel); return new JZlibEncoder(wrapper, compressionLevel);
} else { } else {
return new JdkZlibEncoder(wrapper, compressionLevel); return new JdkZlibEncoder(wrapper, compressionLevel);
@ -47,7 +47,7 @@ public final class ZlibCodecFactory {
} }
public static ZlibEncoder newZlibEncoder(ZlibWrapper wrapper, int compressionLevel, int windowBits, int memLevel) { public static ZlibEncoder newZlibEncoder(ZlibWrapper wrapper, int compressionLevel, int windowBits, int memLevel) {
if (DetectionUtil.javaVersion() < 7) { if (PlatformDependent.javaVersion() < 7) {
return new JZlibEncoder(wrapper, compressionLevel, windowBits, memLevel); return new JZlibEncoder(wrapper, compressionLevel, windowBits, memLevel);
} else { } else {
return new JdkZlibEncoder(wrapper, compressionLevel); return new JdkZlibEncoder(wrapper, compressionLevel);
@ -55,7 +55,7 @@ public final class ZlibCodecFactory {
} }
public static ZlibEncoder newZlibEncoder(byte[] dictionary) { public static ZlibEncoder newZlibEncoder(byte[] dictionary) {
if (DetectionUtil.javaVersion() < 7) { if (PlatformDependent.javaVersion() < 7) {
return new JZlibEncoder(dictionary); return new JZlibEncoder(dictionary);
} else { } else {
return new JdkZlibEncoder(dictionary); return new JdkZlibEncoder(dictionary);
@ -63,7 +63,7 @@ public final class ZlibCodecFactory {
} }
public static ZlibEncoder newZlibEncoder(int compressionLevel, byte[] dictionary) { public static ZlibEncoder newZlibEncoder(int compressionLevel, byte[] dictionary) {
if (DetectionUtil.javaVersion() < 7) { if (PlatformDependent.javaVersion() < 7) {
return new JZlibEncoder(compressionLevel, dictionary); return new JZlibEncoder(compressionLevel, dictionary);
} else { } else {
return new JdkZlibEncoder(compressionLevel, dictionary); return new JdkZlibEncoder(compressionLevel, dictionary);
@ -71,7 +71,7 @@ public final class ZlibCodecFactory {
} }
public static ZlibEncoder newZlibEncoder(int compressionLevel, int windowBits, int memLevel, byte[] dictionary) { public static ZlibEncoder newZlibEncoder(int compressionLevel, int windowBits, int memLevel, byte[] dictionary) {
if (DetectionUtil.javaVersion() < 7) { if (PlatformDependent.javaVersion() < 7) {
return new JZlibEncoder(compressionLevel, windowBits, memLevel, dictionary); return new JZlibEncoder(compressionLevel, windowBits, memLevel, dictionary);
} else { } else {
return new JdkZlibEncoder(compressionLevel, dictionary); return new JdkZlibEncoder(compressionLevel, dictionary);

View File

@ -21,7 +21,7 @@ import io.netty.monitor.EventRateMonitor;
import io.netty.monitor.MonitorName; import io.netty.monitor.MonitorName;
import io.netty.monitor.MonitorRegistry; import io.netty.monitor.MonitorRegistry;
import io.netty.monitor.ValueDistributionMonitor; import io.netty.monitor.ValueDistributionMonitor;
import io.netty.util.internal.DetectionUtil; import io.netty.util.internal.PlatformDependent;
import io.netty.util.internal.SharedResourceMisuseDetector; import io.netty.util.internal.SharedResourceMisuseDetector;
import java.util.ArrayList; import java.util.ArrayList;
@ -548,7 +548,7 @@ public class HashedWheelTimer implements Timer {
// the JVM if it runs on windows. // the JVM if it runs on windows.
// //
// See https://github.com/netty/netty/issues/356 // See https://github.com/netty/netty/issues/356
if (DetectionUtil.isWindows()) { if (PlatformDependent.isWindows()) {
sleepTime = sleepTime / 10 * 10; sleepTime = sleepTime / 10 * 10;
} }

View File

@ -1,73 +0,0 @@
/*
* Copyright 2013 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.util.internal;
import sun.misc.Cleaner;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
// This resist in common because otherwise we would produce a cycle dependency between common and buffer.
public final class DirectByteBufUtil {
private static final Field CLEANER_FIELD;
static {
ByteBuffer direct = ByteBuffer.allocateDirect(1);
Field cleanerField;
try {
cleanerField = direct.getClass().getDeclaredField("cleaner");
cleanerField.setAccessible(true);
Cleaner cleaner = (Cleaner) cleanerField.get(direct);
cleaner.clean();
} catch (Throwable t) {
cleanerField = null;
}
CLEANER_FIELD = cleanerField;
}
/**
* Try to clean a direct {@link ByteBuffer}.
*
* Only try to access this method when {@link DetectionUtil#canFreeDirectBuffer()} returns
* {@code true}
*
*/
public static void freeDirect(ByteBuffer buffer) {
if (!buffer.isDirect()) {
return;
}
if (CLEANER_FIELD == null) {
// Doomed to wait for GC.
return;
}
Cleaner cleaner;
try {
cleaner = (Cleaner) CLEANER_FIELD.get(buffer);
cleaner.clean();
} catch (Throwable t) {
// Nothing we can do here.
}
}
static boolean canFreeDirect() {
return CLEANER_FIELD != null;
}
private DirectByteBufUtil() {
}
}

View File

@ -15,14 +15,12 @@
*/ */
package io.netty.util.internal; package io.netty.util.internal;
import java.lang.reflect.Field;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.security.AccessController; import java.nio.ByteBuffer;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Locale; import java.util.Locale;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -34,22 +32,108 @@ import java.util.regex.Pattern;
* You can disable the use of {@code sun.misc.Unsafe} if you specify * You can disable the use of {@code sun.misc.Unsafe} if you specify
* the system property <strong>io.netty.noUnsafe</strong>. * the system property <strong>io.netty.noUnsafe</strong>.
*/ */
public final class DetectionUtil { public final class PlatformDependent {
private static final ClassLoader LOADER = ClassLoader.getSystemClassLoader();
private static final boolean IS_ANDROID = isAndroid0();
private static final boolean IS_WINDOWS = isWindows0();
private static final boolean IS_ROOT = isRoot0();
private static final int JAVA_VERSION = javaVersion0(); private static final int JAVA_VERSION = javaVersion0();
private static final boolean HAS_UNSAFE = hasUnsafe(AtomicInteger.class.getClassLoader());
private static final boolean CAN_FREE_DIRECT_BUFFER;
private static final boolean IS_WINDOWS;
private static final boolean IS_ROOT;
static { private static final boolean HAS_UNSAFE = hasUnsafe0();
private static final boolean CAN_FREE_DIRECT_BUFFER = canFreeDirectBuffer0();
private static final boolean IS_UNALIGNED = isUnaligned0();
/**
* Returns {@code true} if and only if the current platform is Android
*/
public static boolean isAndroid() {
return IS_ANDROID;
}
/**
* Return {@code true} if the JVM is running on Windows
*/
public static boolean isWindows() {
return IS_WINDOWS;
}
/**
* Return {@code true} if the current user is root. Note that this method returns
* {@code false} if on Windows.
*/
public static boolean isRoot() {
return IS_ROOT;
}
/**
* Return the version of Java under which this library is used.
*/
public static int javaVersion() {
return JAVA_VERSION;
}
/**
* Return {@code true} if {@code sun.misc.Unsafe} was found on the classpath and can be used.
*/
public static boolean hasUnsafe() {
return HAS_UNSAFE;
}
/**
* Return {@code true} if direct buffers can be freed using an optimized way and so memory footprint will be very
* small.
*/
public static boolean canFreeDirectBuffer() {
return CAN_FREE_DIRECT_BUFFER;
}
/**
* Returns {@code true} if and only if {@code java.nio.Bits.unaligned()} is true.
*/
public static boolean isUnaligned() {
return IS_UNALIGNED;
}
/**
* Try to deallocate the specified direct {@link ByteBuffer}. Please note this method does nothing if
* the current platform does not support this operation or the specified buffer is not a direct buffer.
*/
public static void freeDirectBuffer(ByteBuffer buffer) {
if (canFreeDirectBuffer() && buffer.isDirect()) {
PlatformDependent0.freeDirectBuffer(buffer);
}
}
public static Object getObject(Object object, long fieldOffset) {
return PlatformDependent0.getObject(object, fieldOffset);
}
public static long objectFieldOffset(Field field) {
return PlatformDependent0.objectFieldOffset(field);
}
private static boolean isAndroid0() {
boolean android;
try {
Class.forName("android.app.Application", false, LOADER);
android = true;
} catch (Exception e) {
android = false;
}
return android;
}
private static boolean isWindows0() {
return SystemPropertyUtil.get("os.name", "").toLowerCase(Locale.US).contains("win");
}
private static boolean isRoot0() {
Pattern PERMISSION_DENIED = Pattern.compile(".*permission.*denied.*"); Pattern PERMISSION_DENIED = Pattern.compile(".*permission.*denied.*");
String os = SystemPropertyUtil.get("os.name", "").toLowerCase(Locale.UK);
// windows
IS_WINDOWS = os.contains("win");
boolean root = false; boolean root = false;
if (!IS_WINDOWS) { if (!isWindows()) {
for (int i = 1023; i > 0; i --) { for (int i = 1023; i > 0; i --) {
ServerSocket ss = null; ServerSocket ss = null;
try { try {
@ -80,97 +164,7 @@ public final class DetectionUtil {
} }
} }
} }
return root;
IS_ROOT = root;
boolean canFreeDirectBuffer = false;
// Only try to use DirectByteBufUtil if it is not android as otherwise it will give errors because
// it try to access sun.misc.Cleaner
if (!isAndroid()) {
try {
canFreeDirectBuffer = DirectByteBufUtil.canFreeDirect();
} catch (Throwable t) {
// Ignore.
}
}
CAN_FREE_DIRECT_BUFFER = canFreeDirectBuffer;
}
/**
* Return {@code true} if the JVM is running on Windows
*/
public static boolean isWindows() {
return IS_WINDOWS;
}
/**
* Return {@code true} if the current user is root. Note that this method returns
* {@code false} if on Windows.
*/
public static boolean isRoot() {
return IS_ROOT;
}
/**
* Return {@code true} if {@link sun.misc.Unsafe} was found on the classpath and can be used.
*/
public static boolean hasUnsafe() {
return HAS_UNSAFE;
}
/**
* Return the version of Java under which this library is used.
*/
public static int javaVersion() {
return JAVA_VERSION;
}
/**
* Return {@code true} if direct buffers can be freed using an optimized way and so memory footprint will be very
* small.
*/
public static boolean canFreeDirectBuffer() {
return CAN_FREE_DIRECT_BUFFER;
}
private static boolean hasUnsafe(ClassLoader loader) {
boolean noUnsafe = SystemPropertyUtil.getBoolean("io.netty.noUnsafe", false);
if (noUnsafe) {
return false;
}
// Legacy properties
boolean tryUnsafe;
if (SystemPropertyUtil.contains("io.netty.tryUnsafe")) {
tryUnsafe = SystemPropertyUtil.getBoolean("io.netty.tryUnsafe", true);
} else {
tryUnsafe = SystemPropertyUtil.getBoolean("org.jboss.netty.tryUnsafe", true);
}
if (!tryUnsafe) {
return false;
}
try {
Class<?> unsafeClazz = Class.forName("sun.misc.Unsafe", true, loader);
return hasUnsafeField(unsafeClazz);
} catch (Exception e) {
// Ignore
}
return false;
}
private static boolean hasUnsafeField(final Class<?> unsafeClass) throws PrivilegedActionException {
return AccessController.doPrivileged(new PrivilegedExceptionAction<Boolean>() {
@Override
public Boolean run() throws Exception {
unsafeClass.getDeclaredField("theUnsafe");
return true;
}
});
} }
private static int javaVersion0() { private static int javaVersion0() {
@ -191,18 +185,48 @@ public final class DetectionUtil {
return 6; return 6;
} }
private static boolean isAndroid() { private static boolean hasUnsafe0() {
// Android if (isAndroid()) {
try { return false;
Class.forName("android.app.Application", false, ClassLoader.getSystemClassLoader());
return true;
} catch (Exception e) {
// Ignore
} }
return false;
boolean noUnsafe = SystemPropertyUtil.getBoolean("io.netty.noUnsafe", false);
if (noUnsafe) {
return false;
}
// Legacy properties
boolean tryUnsafe;
if (SystemPropertyUtil.contains("io.netty.tryUnsafe")) {
tryUnsafe = SystemPropertyUtil.getBoolean("io.netty.tryUnsafe", true);
} else {
tryUnsafe = SystemPropertyUtil.getBoolean("org.jboss.netty.tryUnsafe", true);
}
if (!tryUnsafe) {
return false;
}
return PlatformDependent0.hasUnsafe();
} }
private DetectionUtil() { private static boolean canFreeDirectBuffer0() {
if (isAndroid()) {
return false;
}
return PlatformDependent0.canFreeDirectBuffer();
}
private static boolean isUnaligned0() {
if (!hasUnsafe()) {
return false;
}
return PlatformDependent0.isUnaligned();
}
private PlatformDependent() {
// only static method supported // only static method supported
} }
} }

View File

@ -0,0 +1,102 @@
/*
* Copyright 2013 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.util.internal;
import sun.misc.Cleaner;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
/**
* The {@link PlatformDependent} operations which requires access to {@code sun.misc.*}.
*/
final class PlatformDependent0 {
private static final Unsafe UNSAFE;
private static final Field CLEANER_FIELD;
private static final boolean UNALIGNED;
static {
Unsafe unsafe;
try {
Field singleoneInstanceField = Unsafe.class.getDeclaredField("theUnsafe");
singleoneInstanceField.setAccessible(true);
unsafe = (Unsafe) singleoneInstanceField.get(null);
} catch (Throwable cause) {
unsafe = null;
}
UNSAFE = unsafe;
ByteBuffer direct = ByteBuffer.allocateDirect(1);
Field cleanerField;
try {
cleanerField = direct.getClass().getDeclaredField("cleaner");
cleanerField.setAccessible(true);
Cleaner cleaner = (Cleaner) cleanerField.get(direct);
cleaner.clean();
} catch (Throwable t) {
cleanerField = null;
}
CLEANER_FIELD = cleanerField;
boolean unaligned;
try {
Class<?> bitsClass = Class.forName("java.nio.Bits", false, ClassLoader.getSystemClassLoader());
Method unalignedMethod = bitsClass.getDeclaredMethod("unaligned");
unalignedMethod.setAccessible(true);
unaligned = Boolean.TRUE.equals(unalignedMethod.invoke(null));
} catch (Throwable t) {
unaligned = false;
}
UNALIGNED = unaligned;
}
static boolean hasUnsafe() {
return UNSAFE != null;
}
static boolean canFreeDirectBuffer() {
return CLEANER_FIELD != null;
}
static void freeDirectBuffer(ByteBuffer buffer) {
Cleaner cleaner;
try {
cleaner = (Cleaner) CLEANER_FIELD.get(buffer);
cleaner.clean();
} catch (Throwable t) {
// Nothing we can do here.
}
}
static boolean isUnaligned() {
return UNALIGNED;
}
static Object getObject(Object object, long fieldOffset) {
return UNSAFE.getObject(object, fieldOffset);
}
static long objectFieldOffset(Field field) {
return UNSAFE.objectFieldOffset(field);
}
private PlatformDependent0() {
}
}

View File

@ -30,7 +30,7 @@ import io.netty.channel.ChannelPromise;
import io.netty.channel.DefaultChannelPromise; import io.netty.channel.DefaultChannelPromise;
import io.netty.logging.InternalLogger; import io.netty.logging.InternalLogger;
import io.netty.logging.InternalLoggerFactory; import io.netty.logging.InternalLoggerFactory;
import io.netty.util.internal.DetectionUtil; import io.netty.util.internal.PlatformDependent;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult; import javax.net.ssl.SSLEngineResult;
@ -659,7 +659,7 @@ public class SslHandler
} }
// also match against SctpChannel via String matching as it may not present. // also match against SctpChannel via String matching as it may not present.
if (DetectionUtil.javaVersion() >= 7 if (PlatformDependent.javaVersion() >= 7
&& "com.sun.nio.sctp.SctpChannel".equals(clazz.getSuperclass().getName())) { && "com.sun.nio.sctp.SctpChannel".equals(clazz.getSuperclass().getName())) {
return true; return true;
} }

View File

@ -21,7 +21,7 @@ import io.netty.buffer.MessageBuf;
import io.netty.logging.InternalLogger; import io.netty.logging.InternalLogger;
import io.netty.logging.InternalLoggerFactory; import io.netty.logging.InternalLoggerFactory;
import io.netty.util.DefaultAttributeMap; import io.netty.util.DefaultAttributeMap;
import io.netty.util.internal.DetectionUtil; import io.netty.util.internal.PlatformDependent;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
@ -631,7 +631,7 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
boolean wasActive = isActive(); boolean wasActive = isActive();
// See: https://github.com/netty/netty/issues/576 // See: https://github.com/netty/netty/issues/576
if (!DetectionUtil.isWindows() && !DetectionUtil.isRoot() && if (!PlatformDependent.isWindows() && !PlatformDependent.isRoot() &&
Boolean.TRUE.equals(config().getOption(ChannelOption.SO_BROADCAST)) && Boolean.TRUE.equals(config().getOption(ChannelOption.SO_BROADCAST)) &&
localAddress instanceof InetSocketAddress && localAddress instanceof InetSocketAddress &&
!((InetSocketAddress) localAddress).getAddress().isAnyLocalAddress()) { !((InetSocketAddress) localAddress).getAddress().isAnyLocalAddress()) {

View File

@ -21,7 +21,7 @@ import io.netty.channel.ChannelOption;
import io.netty.channel.DefaultChannelConfig; import io.netty.channel.DefaultChannelConfig;
import io.netty.logging.InternalLogger; import io.netty.logging.InternalLogger;
import io.netty.logging.InternalLoggerFactory; import io.netty.logging.InternalLoggerFactory;
import io.netty.util.internal.DetectionUtil; import io.netty.util.internal.PlatformDependent;
import java.io.IOException; import java.io.IOException;
import java.net.DatagramSocket; import java.net.DatagramSocket;
@ -146,7 +146,7 @@ public class DefaultDatagramChannelConfig extends DefaultChannelConfig implement
try { try {
// See: https://github.com/netty/netty/issues/576 // See: https://github.com/netty/netty/issues/576
if (broadcast && if (broadcast &&
!DetectionUtil.isWindows() && !DetectionUtil.isRoot() && !PlatformDependent.isWindows() && !PlatformDependent.isRoot() &&
!javaSocket.getLocalAddress().isAnyLocalAddress()) { !javaSocket.getLocalAddress().isAnyLocalAddress()) {
// Warn a user about the fact that a non-root user can't receive a // Warn a user about the fact that a non-root user can't receive a
// broadcast packet on *nix if the socket is bound on non-wildcard address. // broadcast packet on *nix if the socket is bound on non-wildcard address.

View File

@ -22,7 +22,7 @@ import io.netty.channel.EventLoopException;
import io.netty.channel.MultithreadEventLoopGroup; import io.netty.channel.MultithreadEventLoopGroup;
import io.netty.logging.InternalLogger; import io.netty.logging.InternalLogger;
import io.netty.logging.InternalLoggerFactory; import io.netty.logging.InternalLoggerFactory;
import io.netty.util.internal.DetectionUtil; import io.netty.util.internal.PlatformDependent;
import java.io.IOException; import java.io.IOException;
import java.nio.channels.AsynchronousChannelGroup; import java.nio.channels.AsynchronousChannelGroup;
@ -44,7 +44,7 @@ public class AioEventLoopGroup extends MultithreadEventLoopGroup {
static { static {
AioChannelFinder finder; AioChannelFinder finder;
try { try {
if (DetectionUtil.hasUnsafe()) { if (PlatformDependent.hasUnsafe()) {
finder = new UnsafeAioChannelFinder(); finder = new UnsafeAioChannelFinder();
} else { } else {
finder = new ReflectiveAioChannelFinder(); finder = new ReflectiveAioChannelFinder();

View File

@ -15,19 +15,16 @@
*/ */
package io.netty.channel.socket.aio; package io.netty.channel.socket.aio;
import io.netty.util.internal.PlatformDependent;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import sun.misc.Unsafe;
/** /**
* {@link AioChannelFinder} implementation which will use {@link Unsafe}. * {@link AioChannelFinder} implementation which uses {@code sun.misc.Unsafe}.
*/ */
@SuppressWarnings("restriction")
final class UnsafeAioChannelFinder implements AioChannelFinder { final class UnsafeAioChannelFinder implements AioChannelFinder {
private static final Unsafe UNSAFE = getUnsafe();
private static volatile Map<Class<?>, Long> offsetCache = new HashMap<Class<?>, Long>(); private static volatile Map<Class<?>, Long> offsetCache = new HashMap<Class<?>, Long>();
@Override @Override
@ -38,7 +35,7 @@ final class UnsafeAioChannelFinder implements AioChannelFinder {
if (offset == null) { if (offset == null) {
return null; return null;
} }
Object next = UNSAFE.getObject(command, offset); Object next = PlatformDependent.getObject(command, offset);
if (next instanceof AbstractAioChannel) { if (next instanceof AbstractAioChannel) {
return (AbstractAioChannel) next; return (AbstractAioChannel) next;
} }
@ -56,7 +53,7 @@ final class UnsafeAioChannelFinder implements AioChannelFinder {
for (Field f: commandType.getDeclaredFields()) { for (Field f: commandType.getDeclaredFields()) {
if (f.getType() == Runnable.class) { if (f.getType() == Runnable.class) {
res = UNSAFE.objectFieldOffset(f); res = PlatformDependent.objectFieldOffset(f);
put(offsetCache, commandType, res); put(offsetCache, commandType, res);
return res; return res;
} }
@ -65,7 +62,7 @@ final class UnsafeAioChannelFinder implements AioChannelFinder {
f.setAccessible(true); f.setAccessible(true);
Object candidate = f.get(command); Object candidate = f.get(command);
if (candidate instanceof AbstractAioChannel) { if (candidate instanceof AbstractAioChannel) {
res = UNSAFE.objectFieldOffset(f); res = PlatformDependent.objectFieldOffset(f);
put(offsetCache, commandType, res); put(offsetCache, commandType, res);
return res; return res;
} }
@ -80,14 +77,4 @@ final class UnsafeAioChannelFinder implements AioChannelFinder {
newCache.put(key, value); newCache.put(key, value);
offsetCache = newCache; offsetCache = newCache;
} }
private static Unsafe getUnsafe() {
try {
Field singleoneInstanceField = Unsafe.class.getDeclaredField("theUnsafe");
singleoneInstanceField.setAccessible(true);
return (Unsafe) singleoneInstanceField.get(null);
} catch (Throwable cause) {
throw new RuntimeException("Error while obtaining sun.misc.Unsafe", cause);
}
}
} }

View File

@ -25,7 +25,7 @@ import io.netty.channel.ChannelPromise;
import io.netty.channel.socket.DatagramChannelConfig; import io.netty.channel.socket.DatagramChannelConfig;
import io.netty.channel.socket.DatagramPacket; import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.InternetProtocolFamily; import io.netty.channel.socket.InternetProtocolFamily;
import io.netty.util.internal.DetectionUtil; import io.netty.util.internal.PlatformDependent;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
@ -69,7 +69,7 @@ public final class NioDatagramChannel
return newSocket(); return newSocket();
} }
if (DetectionUtil.javaVersion() < 7) { if (PlatformDependent.javaVersion() < 7) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@ -309,7 +309,7 @@ public final class NioDatagramChannel
public ChannelFuture joinGroup( public ChannelFuture joinGroup(
InetAddress multicastAddress, NetworkInterface networkInterface, InetAddress multicastAddress, NetworkInterface networkInterface,
InetAddress source, ChannelPromise promise) { InetAddress source, ChannelPromise promise) {
if (DetectionUtil.javaVersion() >= 7) { if (PlatformDependent.javaVersion() >= 7) {
if (multicastAddress == null) { if (multicastAddress == null) {
throw new NullPointerException("multicastAddress"); throw new NullPointerException("multicastAddress");
} }
@ -384,7 +384,7 @@ public final class NioDatagramChannel
public ChannelFuture leaveGroup( public ChannelFuture leaveGroup(
InetAddress multicastAddress, NetworkInterface networkInterface, InetAddress source, InetAddress multicastAddress, NetworkInterface networkInterface, InetAddress source,
ChannelPromise promise) { ChannelPromise promise) {
if (DetectionUtil.javaVersion() < 7) { if (PlatformDependent.javaVersion() < 7) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
if (multicastAddress == null) { if (multicastAddress == null) {
@ -438,7 +438,7 @@ public final class NioDatagramChannel
public ChannelFuture block( public ChannelFuture block(
InetAddress multicastAddress, NetworkInterface networkInterface, InetAddress multicastAddress, NetworkInterface networkInterface,
InetAddress sourceToBlock, ChannelPromise promise) { InetAddress sourceToBlock, ChannelPromise promise) {
if (DetectionUtil.javaVersion() < 7) { if (PlatformDependent.javaVersion() < 7) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} else { } else {
if (multicastAddress == null) { if (multicastAddress == null) {

View File

@ -18,7 +18,7 @@ package io.netty.channel.socket.nio;
import io.netty.channel.ChannelException; import io.netty.channel.ChannelException;
import io.netty.channel.socket.DatagramChannelConfig; import io.netty.channel.socket.DatagramChannelConfig;
import io.netty.channel.socket.DefaultDatagramChannelConfig; import io.netty.channel.socket.DefaultDatagramChannelConfig;
import io.netty.util.internal.DetectionUtil; import io.netty.util.internal.PlatformDependent;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.InetAddress; import java.net.InetAddress;
@ -162,7 +162,7 @@ class NioDatagramChannelConfig extends DefaultDatagramChannelConfig {
} }
private Object getOption0(Object option) { private Object getOption0(Object option) {
if (DetectionUtil.javaVersion() < 7) { if (PlatformDependent.javaVersion() < 7) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} else { } else {
try { try {
@ -174,7 +174,7 @@ class NioDatagramChannelConfig extends DefaultDatagramChannelConfig {
} }
private void setOption0(Object option, Object value) { private void setOption0(Object option, Object value) {
if (DetectionUtil.javaVersion() < 7) { if (PlatformDependent.javaVersion() < 7) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} else { } else {
try { try {