All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.netty.util.internal.PlatformDependent Maven / Gradle / Ivy

There is a newer version: 5.0.0.Alpha2
Show newest version
/*
 * Copyright 2012 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 io.netty.util.internal.chmv8.ConcurrentHashMapV8;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;

import java.lang.reflect.Field;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.regex.Pattern;


/**
 * Utility that detects various properties specific to the current runtime
 * environment, such as Java version and the availability of the
 * {@code sun.misc.Unsafe} object.
 * 

* You can disable the use of {@code sun.misc.Unsafe} if you specify * the system property io.netty.noUnsafe. */ public final class PlatformDependent { 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 CAN_ENABLE_TCP_NODELAY_BY_DEFAULT = !isAndroid(); private static final boolean HAS_UNSAFE = hasUnsafe0(); private static final boolean CAN_USE_CHM_V8 = HAS_UNSAFE && JAVA_VERSION < 8; private static final boolean DIRECT_BUFFER_PREFERRED = HAS_UNSAFE && SystemPropertyUtil.getBoolean("io.netty.preferDirect", false); private static final long ARRAY_BASE_OFFSET = arrayBaseOffset0(); private static final boolean HAS_JAVASSIST = hasJavassist0(); static { InternalLogger logger = InternalLoggerFactory.getInstance(PlatformDependent.class); if (!hasUnsafe()) { logger.warn( "Your platform does not provide complete low-level API for accessing direct buffers reliably. " + "Unless explicitly requested, heap buffer will always be preferred " + "to avoid potential risk of getting OutOfMemoryError."); } } /** * 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; } /** * Returns {@code true} if and only if it is fine to enable TCP_NODELAY socket option by default. */ public static boolean canEnableTcpNoDelayByDefault() { return CAN_ENABLE_TCP_NODELAY_BY_DEFAULT; } /** * Return {@code true} if {@code sun.misc.Unsafe} was found on the classpath and can be used for acclerated * direct memory access. */ public static boolean hasUnsafe() { return HAS_UNSAFE; } /** * Returns {@code true} if the platform has reliable low-level direct buffer access API and a user specified * {@code -Dio.netty.preferDirect} option. */ public static boolean directBufferPreferred() { return DIRECT_BUFFER_PREFERRED; } /** * Returns {@code true} if and only if Javassist is available. */ public static boolean hasJavassist() { return HAS_JAVASSIST; } /** * Raises an exception bypassing compiler checks for checked exceptions. */ public static void throwException(Throwable t) { if (hasUnsafe()) { PlatformDependent0.throwException(t); } else { PlatformDependent.throwException0(t); } } @SuppressWarnings("unchecked") private static void throwException0(Throwable t) throws E { throw (E) t; } /** * Creates a new fastest {@link ConcurrentMap} implementaion for the current platform. */ public static ConcurrentMap newConcurrentHashMap() { if (CAN_USE_CHM_V8) { return new ConcurrentHashMapV8(); } else { return new ConcurrentHashMap(); } } /** * Creates a new fastest {@link ConcurrentMap} implementaion for the current platform. */ public static ConcurrentMap newConcurrentHashMap(int initialCapacity) { if (CAN_USE_CHM_V8) { return new ConcurrentHashMapV8(initialCapacity); } else { return new ConcurrentHashMap(initialCapacity); } } /** * Creates a new fastest {@link ConcurrentMap} implementaion for the current platform. */ public static ConcurrentMap newConcurrentHashMap(int initialCapacity, float loadFactor) { if (CAN_USE_CHM_V8) { return new ConcurrentHashMapV8(initialCapacity, loadFactor); } else { return new ConcurrentHashMap(initialCapacity, loadFactor); } } /** * Creates a new fastest {@link ConcurrentMap} implementaion for the current platform. */ public static ConcurrentMap newConcurrentHashMap( int initialCapacity, float loadFactor, int concurrencyLevel) { if (CAN_USE_CHM_V8) { return new ConcurrentHashMapV8(initialCapacity, loadFactor, concurrencyLevel); } else { return new ConcurrentHashMap(initialCapacity, loadFactor, concurrencyLevel); } } /** * Creates a new fastest {@link ConcurrentMap} implementaion for the current platform. */ public static ConcurrentMap newConcurrentHashMap(Map map) { if (CAN_USE_CHM_V8) { return new ConcurrentHashMapV8(map); } else { return new ConcurrentHashMap(map); } } /** * 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 (buffer.isDirect()) { PlatformDependent0.freeDirectBuffer(buffer); } } public static long directBufferAddress(ByteBuffer buffer) { return PlatformDependent0.directBufferAddress(buffer); } public static Object getObject(Object object, long fieldOffset) { return PlatformDependent0.getObject(object, fieldOffset); } public static int getInt(Object object, long fieldOffset) { return PlatformDependent0.getInt(object, fieldOffset); } public static long objectFieldOffset(Field field) { return PlatformDependent0.objectFieldOffset(field); } public static byte getByte(long address) { return PlatformDependent0.getByte(address); } public static short getShort(long address) { return PlatformDependent0.getShort(address); } public static int getInt(long address) { return PlatformDependent0.getInt(address); } public static long getLong(long address) { return PlatformDependent0.getLong(address); } public static void putByte(long address, byte value) { PlatformDependent0.putByte(address, value); } public static void putShort(long address, short value) { PlatformDependent0.putShort(address, value); } public static void putInt(long address, int value) { PlatformDependent0.putInt(address, value); } public static void putLong(long address, long value) { PlatformDependent0.putLong(address, value); } public static void copyMemory(long srcAddr, long dstAddr, long length) { PlatformDependent0.copyMemory(srcAddr, dstAddr, length); } public static void copyMemory(byte[] src, int srcIndex, long dstAddr, long length) { PlatformDependent0.copyMemory(src, ARRAY_BASE_OFFSET + srcIndex, null, dstAddr, length); } public static void copyMemory(long srcAddr, byte[] dst, int dstIndex, long length) { PlatformDependent0.copyMemory(null, srcAddr, dst, ARRAY_BASE_OFFSET + dstIndex, length); } private static boolean isAndroid0() { boolean android; try { Class.forName("android.app.Application", false, ClassLoader.getSystemClassLoader()); 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.*"); boolean root = false; if (!isWindows()) { for (int i = 1023; i > 0; i --) { ServerSocket ss = null; try { ss = new ServerSocket(); ss.setReuseAddress(true); ss.bind(new InetSocketAddress(i)); root = true; break; } catch (Exception e) { // Failed to bind. // Check the error message so that we don't always need to bind 1023 times. String message = e.getMessage(); if (message == null) { message = ""; } message = message.toLowerCase(); if (PERMISSION_DENIED.matcher(message).matches()) { break; } } finally { if (ss != null) { try { ss.close(); } catch (Exception e) { // Ignore. } } } } } return root; } private static int javaVersion0() { // Android if (isAndroid()) { return 6; } try { Class.forName("java.time.Clock", false, Object.class.getClassLoader()); return 8; } catch (Exception e) { // Ignore } try { Class.forName("java.util.concurrent.LinkedTransferQueue", false, BlockingQueue.class.getClassLoader()); return 7; } catch (Exception e) { // Ignore } return 6; } private static boolean hasUnsafe0() { if (isAndroid()) { 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; } try { return PlatformDependent0.hasUnsafe(); } catch (Throwable t) { return false; } } private static long arrayBaseOffset0() { if (!hasUnsafe()) { return -1; } return PlatformDependent0.arrayBaseOffset(); } private static boolean hasJavassist0() { boolean noJavassist = SystemPropertyUtil.getBoolean("io.netty.noJavassist", false); if (noJavassist) { return false; } try { JavassistTypeParameterMatcherGenerator.generate(Object.class, PlatformDependent.class.getClassLoader()); return true; } catch (Throwable t) { return false; } } private PlatformDependent() { // only static method supported } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy