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:
parent
5b5b39a606
commit
64ae8b6a37
@ -15,7 +15,7 @@
|
||||
*/
|
||||
package io.netty.buffer;
|
||||
|
||||
import io.netty.util.internal.DetectionUtil;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -699,7 +699,7 @@ public class DefaultCompositeByteBuf extends AbstractByteBuf implements Composit
|
||||
@Override
|
||||
public int getBytes(int index, GatheringByteChannel out, int length)
|
||||
throws IOException {
|
||||
if (DetectionUtil.javaVersion() < 7) {
|
||||
if (PlatformDependent.javaVersion() < 7) {
|
||||
// XXX Gathering write is not supported because of a known issue.
|
||||
// See http://bugs.sun.com/view_bug.do?bug_id=6210541
|
||||
return out.write(copiedNioBuffer(index, length));
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package io.netty.buffer;
|
||||
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
@ -370,7 +371,7 @@ abstract class PoolArena<T> {
|
||||
|
||||
@Override
|
||||
protected void destroyChunk(PoolChunk<ByteBuffer> chunk) {
|
||||
UnpooledDirectByteBuf.freeDirect(chunk.memory);
|
||||
PlatformDependent.freeDirectBuffer(chunk.memory);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
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.
|
||||
@ -41,7 +41,7 @@ public final class UnpooledByteBufAllocator extends AbstractByteBufAllocator {
|
||||
|
||||
@Override
|
||||
public ByteBuf ioBuffer() {
|
||||
if (DetectionUtil.canFreeDirectBuffer()) {
|
||||
if (PlatformDependent.canFreeDirectBuffer()) {
|
||||
return directBuffer(0);
|
||||
}
|
||||
|
||||
|
@ -15,8 +15,7 @@
|
||||
*/
|
||||
package io.netty.buffer;
|
||||
|
||||
import io.netty.util.internal.DetectionUtil;
|
||||
import io.netty.util.internal.DirectByteBufUtil;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -109,7 +108,7 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
|
||||
doNotFree = false;
|
||||
} else {
|
||||
if (suspendedDeallocations == null) {
|
||||
freeDirect(oldBuffer);
|
||||
PlatformDependent.freeDirectBuffer(oldBuffer);
|
||||
} else {
|
||||
suspendedDeallocations.add(oldBuffer);
|
||||
}
|
||||
@ -471,7 +470,7 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
|
||||
}
|
||||
|
||||
resumeIntermediaryDeallocations();
|
||||
freeDirect(buffer);
|
||||
PlatformDependent.freeDirectBuffer(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -492,7 +491,7 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
|
||||
this.suspendedDeallocations = null;
|
||||
|
||||
for (ByteBuffer buf: suspendedDeallocations) {
|
||||
freeDirect(buf);
|
||||
PlatformDependent.freeDirectBuffer(buf);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -501,10 +500,4 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
|
||||
public ByteBuf unwrap() {
|
||||
return null;
|
||||
}
|
||||
|
||||
static void freeDirect(ByteBuffer buffer) {
|
||||
if (DetectionUtil.canFreeDirectBuffer()) {
|
||||
DirectByteBufUtil.freeDirect(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,14 +16,14 @@
|
||||
package io.netty.handler.codec.spdy;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.util.internal.DetectionUtil;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
|
||||
abstract class SpdyHeaderBlockCompressor {
|
||||
|
||||
static SpdyHeaderBlockCompressor newInstance(
|
||||
int version, int compressionLevel, int windowBits, int memLevel) {
|
||||
|
||||
if (DetectionUtil.javaVersion() >= 7) {
|
||||
if (PlatformDependent.javaVersion() >= 7) {
|
||||
return new SpdyHeaderBlockZlibCompressor(
|
||||
version, compressionLevel);
|
||||
} else {
|
||||
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
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}.
|
||||
@ -23,7 +23,7 @@ import io.netty.util.internal.DetectionUtil;
|
||||
public final class ZlibCodecFactory {
|
||||
|
||||
public static ZlibEncoder newZlibEncoder(int compressionLevel) {
|
||||
if (DetectionUtil.javaVersion() < 7) {
|
||||
if (PlatformDependent.javaVersion() < 7) {
|
||||
return new JZlibEncoder(compressionLevel);
|
||||
} else {
|
||||
return new JdkZlibEncoder(compressionLevel);
|
||||
@ -31,7 +31,7 @@ public final class ZlibCodecFactory {
|
||||
}
|
||||
|
||||
public static ZlibEncoder newZlibEncoder(ZlibWrapper wrapper) {
|
||||
if (DetectionUtil.javaVersion() < 7) {
|
||||
if (PlatformDependent.javaVersion() < 7) {
|
||||
return new JZlibEncoder(wrapper);
|
||||
} else {
|
||||
return new JdkZlibEncoder(wrapper);
|
||||
@ -39,7 +39,7 @@ public final class ZlibCodecFactory {
|
||||
}
|
||||
|
||||
public static ZlibEncoder newZlibEncoder(ZlibWrapper wrapper, int compressionLevel) {
|
||||
if (DetectionUtil.javaVersion() < 7) {
|
||||
if (PlatformDependent.javaVersion() < 7) {
|
||||
return new JZlibEncoder(wrapper, compressionLevel);
|
||||
} else {
|
||||
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) {
|
||||
if (DetectionUtil.javaVersion() < 7) {
|
||||
if (PlatformDependent.javaVersion() < 7) {
|
||||
return new JZlibEncoder(wrapper, compressionLevel, windowBits, memLevel);
|
||||
} else {
|
||||
return new JdkZlibEncoder(wrapper, compressionLevel);
|
||||
@ -55,7 +55,7 @@ public final class ZlibCodecFactory {
|
||||
}
|
||||
|
||||
public static ZlibEncoder newZlibEncoder(byte[] dictionary) {
|
||||
if (DetectionUtil.javaVersion() < 7) {
|
||||
if (PlatformDependent.javaVersion() < 7) {
|
||||
return new JZlibEncoder(dictionary);
|
||||
} else {
|
||||
return new JdkZlibEncoder(dictionary);
|
||||
@ -63,7 +63,7 @@ public final class ZlibCodecFactory {
|
||||
}
|
||||
|
||||
public static ZlibEncoder newZlibEncoder(int compressionLevel, byte[] dictionary) {
|
||||
if (DetectionUtil.javaVersion() < 7) {
|
||||
if (PlatformDependent.javaVersion() < 7) {
|
||||
return new JZlibEncoder(compressionLevel, dictionary);
|
||||
} else {
|
||||
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) {
|
||||
if (DetectionUtil.javaVersion() < 7) {
|
||||
if (PlatformDependent.javaVersion() < 7) {
|
||||
return new JZlibEncoder(compressionLevel, windowBits, memLevel, dictionary);
|
||||
} else {
|
||||
return new JdkZlibEncoder(compressionLevel, dictionary);
|
||||
|
@ -21,7 +21,7 @@ import io.netty.monitor.EventRateMonitor;
|
||||
import io.netty.monitor.MonitorName;
|
||||
import io.netty.monitor.MonitorRegistry;
|
||||
import io.netty.monitor.ValueDistributionMonitor;
|
||||
import io.netty.util.internal.DetectionUtil;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
import io.netty.util.internal.SharedResourceMisuseDetector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -548,7 +548,7 @@ public class HashedWheelTimer implements Timer {
|
||||
// the JVM if it runs on windows.
|
||||
//
|
||||
// See https://github.com/netty/netty/issues/356
|
||||
if (DetectionUtil.isWindows()) {
|
||||
if (PlatformDependent.isWindows()) {
|
||||
sleepTime = sleepTime / 10 * 10;
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
}
|
||||
}
|
@ -15,14 +15,12 @@
|
||||
*/
|
||||
package io.netty.util.internal;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
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
|
||||
* 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 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.*");
|
||||
String os = SystemPropertyUtil.get("os.name", "").toLowerCase(Locale.UK);
|
||||
// windows
|
||||
IS_WINDOWS = os.contains("win");
|
||||
|
||||
boolean root = false;
|
||||
if (!IS_WINDOWS) {
|
||||
if (!isWindows()) {
|
||||
for (int i = 1023; i > 0; i --) {
|
||||
ServerSocket ss = null;
|
||||
try {
|
||||
@ -80,97 +164,7 @@ public final class DetectionUtil {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
});
|
||||
return root;
|
||||
}
|
||||
|
||||
private static int javaVersion0() {
|
||||
@ -191,18 +185,48 @@ public final class DetectionUtil {
|
||||
return 6;
|
||||
}
|
||||
|
||||
private static boolean isAndroid() {
|
||||
// Android
|
||||
try {
|
||||
Class.forName("android.app.Application", false, ClassLoader.getSystemClassLoader());
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
private static boolean hasUnsafe0() {
|
||||
if (isAndroid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
private DetectionUtil() {
|
||||
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 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
|
||||
}
|
||||
}
|
@ -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() {
|
||||
}
|
||||
}
|
@ -30,7 +30,7 @@ import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.DefaultChannelPromise;
|
||||
import io.netty.logging.InternalLogger;
|
||||
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.SSLEngineResult;
|
||||
@ -659,7 +659,7 @@ public class SslHandler
|
||||
}
|
||||
|
||||
// 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())) {
|
||||
return true;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import io.netty.buffer.MessageBuf;
|
||||
import io.netty.logging.InternalLogger;
|
||||
import io.netty.logging.InternalLoggerFactory;
|
||||
import io.netty.util.DefaultAttributeMap;
|
||||
import io.netty.util.internal.DetectionUtil;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
@ -631,7 +631,7 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
||||
boolean wasActive = isActive();
|
||||
|
||||
// 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)) &&
|
||||
localAddress instanceof InetSocketAddress &&
|
||||
!((InetSocketAddress) localAddress).getAddress().isAnyLocalAddress()) {
|
||||
|
@ -21,7 +21,7 @@ import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.DefaultChannelConfig;
|
||||
import io.netty.logging.InternalLogger;
|
||||
import io.netty.logging.InternalLoggerFactory;
|
||||
import io.netty.util.internal.DetectionUtil;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramSocket;
|
||||
@ -146,7 +146,7 @@ public class DefaultDatagramChannelConfig extends DefaultChannelConfig implement
|
||||
try {
|
||||
// See: https://github.com/netty/netty/issues/576
|
||||
if (broadcast &&
|
||||
!DetectionUtil.isWindows() && !DetectionUtil.isRoot() &&
|
||||
!PlatformDependent.isWindows() && !PlatformDependent.isRoot() &&
|
||||
!javaSocket.getLocalAddress().isAnyLocalAddress()) {
|
||||
// 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.
|
||||
|
@ -22,7 +22,7 @@ import io.netty.channel.EventLoopException;
|
||||
import io.netty.channel.MultithreadEventLoopGroup;
|
||||
import io.netty.logging.InternalLogger;
|
||||
import io.netty.logging.InternalLoggerFactory;
|
||||
import io.netty.util.internal.DetectionUtil;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.AsynchronousChannelGroup;
|
||||
@ -44,7 +44,7 @@ public class AioEventLoopGroup extends MultithreadEventLoopGroup {
|
||||
static {
|
||||
AioChannelFinder finder;
|
||||
try {
|
||||
if (DetectionUtil.hasUnsafe()) {
|
||||
if (PlatformDependent.hasUnsafe()) {
|
||||
finder = new UnsafeAioChannelFinder();
|
||||
} else {
|
||||
finder = new ReflectiveAioChannelFinder();
|
||||
|
@ -15,19 +15,16 @@
|
||||
*/
|
||||
package io.netty.channel.socket.aio;
|
||||
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
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 {
|
||||
private static final Unsafe UNSAFE = getUnsafe();
|
||||
|
||||
private static volatile Map<Class<?>, Long> offsetCache = new HashMap<Class<?>, Long>();
|
||||
|
||||
@Override
|
||||
@ -38,7 +35,7 @@ final class UnsafeAioChannelFinder implements AioChannelFinder {
|
||||
if (offset == null) {
|
||||
return null;
|
||||
}
|
||||
Object next = UNSAFE.getObject(command, offset);
|
||||
Object next = PlatformDependent.getObject(command, offset);
|
||||
if (next instanceof AbstractAioChannel) {
|
||||
return (AbstractAioChannel) next;
|
||||
}
|
||||
@ -56,7 +53,7 @@ final class UnsafeAioChannelFinder implements AioChannelFinder {
|
||||
|
||||
for (Field f: commandType.getDeclaredFields()) {
|
||||
if (f.getType() == Runnable.class) {
|
||||
res = UNSAFE.objectFieldOffset(f);
|
||||
res = PlatformDependent.objectFieldOffset(f);
|
||||
put(offsetCache, commandType, res);
|
||||
return res;
|
||||
}
|
||||
@ -65,7 +62,7 @@ final class UnsafeAioChannelFinder implements AioChannelFinder {
|
||||
f.setAccessible(true);
|
||||
Object candidate = f.get(command);
|
||||
if (candidate instanceof AbstractAioChannel) {
|
||||
res = UNSAFE.objectFieldOffset(f);
|
||||
res = PlatformDependent.objectFieldOffset(f);
|
||||
put(offsetCache, commandType, res);
|
||||
return res;
|
||||
}
|
||||
@ -80,14 +77,4 @@ final class UnsafeAioChannelFinder implements AioChannelFinder {
|
||||
newCache.put(key, value);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.socket.DatagramChannelConfig;
|
||||
import io.netty.channel.socket.DatagramPacket;
|
||||
import io.netty.channel.socket.InternetProtocolFamily;
|
||||
import io.netty.util.internal.DetectionUtil;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
@ -69,7 +69,7 @@ public final class NioDatagramChannel
|
||||
return newSocket();
|
||||
}
|
||||
|
||||
if (DetectionUtil.javaVersion() < 7) {
|
||||
if (PlatformDependent.javaVersion() < 7) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@ -309,7 +309,7 @@ public final class NioDatagramChannel
|
||||
public ChannelFuture joinGroup(
|
||||
InetAddress multicastAddress, NetworkInterface networkInterface,
|
||||
InetAddress source, ChannelPromise promise) {
|
||||
if (DetectionUtil.javaVersion() >= 7) {
|
||||
if (PlatformDependent.javaVersion() >= 7) {
|
||||
if (multicastAddress == null) {
|
||||
throw new NullPointerException("multicastAddress");
|
||||
}
|
||||
@ -384,7 +384,7 @@ public final class NioDatagramChannel
|
||||
public ChannelFuture leaveGroup(
|
||||
InetAddress multicastAddress, NetworkInterface networkInterface, InetAddress source,
|
||||
ChannelPromise promise) {
|
||||
if (DetectionUtil.javaVersion() < 7) {
|
||||
if (PlatformDependent.javaVersion() < 7) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
if (multicastAddress == null) {
|
||||
@ -438,7 +438,7 @@ public final class NioDatagramChannel
|
||||
public ChannelFuture block(
|
||||
InetAddress multicastAddress, NetworkInterface networkInterface,
|
||||
InetAddress sourceToBlock, ChannelPromise promise) {
|
||||
if (DetectionUtil.javaVersion() < 7) {
|
||||
if (PlatformDependent.javaVersion() < 7) {
|
||||
throw new UnsupportedOperationException();
|
||||
} else {
|
||||
if (multicastAddress == null) {
|
||||
|
@ -18,7 +18,7 @@ package io.netty.channel.socket.nio;
|
||||
import io.netty.channel.ChannelException;
|
||||
import io.netty.channel.socket.DatagramChannelConfig;
|
||||
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.net.InetAddress;
|
||||
@ -162,7 +162,7 @@ class NioDatagramChannelConfig extends DefaultDatagramChannelConfig {
|
||||
}
|
||||
|
||||
private Object getOption0(Object option) {
|
||||
if (DetectionUtil.javaVersion() < 7) {
|
||||
if (PlatformDependent.javaVersion() < 7) {
|
||||
throw new UnsupportedOperationException();
|
||||
} else {
|
||||
try {
|
||||
@ -174,7 +174,7 @@ class NioDatagramChannelConfig extends DefaultDatagramChannelConfig {
|
||||
}
|
||||
|
||||
private void setOption0(Object option, Object value) {
|
||||
if (DetectionUtil.javaVersion() < 7) {
|
||||
if (PlatformDependent.javaVersion() < 7) {
|
||||
throw new UnsupportedOperationException();
|
||||
} else {
|
||||
try {
|
||||
|
Loading…
Reference in New Issue
Block a user