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;
|
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));
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
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 {
|
|
||||||
Class.forName("android.app.Application", false, ClassLoader.getSystemClassLoader());
|
|
||||||
return true;
|
|
||||||
} catch (Exception e) {
|
|
||||||
// Ignore
|
|
||||||
}
|
|
||||||
return false;
|
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
|
// 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.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;
|
||||||
}
|
}
|
||||||
|
@ -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()) {
|
||||||
|
@ -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.
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user