netty cleanup

This commit is contained in:
Sen 2025-05-30 13:30:29 +02:00
parent c8e5c16e41
commit f30141c8f3
Signed by: sen
GPG key ID: 3AC50A6F47D1B722
27 changed files with 51 additions and 418 deletions

View file

@ -26,8 +26,8 @@ import java.nio.charset.Charset;
import common.net.util.IllegalReferenceCountException;
import common.net.util.ResourceLeakDetector;
import common.net.util.internal.PlatformDependent;
import common.net.util.internal.StringUtil;
import common.util.Util;
/**
@ -1030,7 +1030,7 @@ public abstract class AbstractByteBuf extends ByteBuf {
}
} while (i < endIndex);
} catch (Exception e) {
PlatformDependent.throwException(e);
Util.throwUnchecked(e);
}
return -1;
@ -1071,7 +1071,7 @@ public abstract class AbstractByteBuf extends ByteBuf {
}
} while (i >= index);
} catch (Exception e) {
PlatformDependent.throwException(e);
Util.throwUnchecked(e);
}
return -1;

View file

@ -19,7 +19,6 @@ package common.net.buffer;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import common.net.util.IllegalReferenceCountException;
import common.net.util.internal.PlatformDependent;
/**
* Abstract base class for {@link ByteBuf} implementations that count references.
@ -30,7 +29,7 @@ public abstract class AbstractReferenceCountedByteBuf extends AbstractByteBuf {
static {
AtomicIntegerFieldUpdater<AbstractReferenceCountedByteBuf> updater =
PlatformDependent.newAtomicIntegerFieldUpdater(AbstractReferenceCountedByteBuf.class, "refCnt");
null;
if (updater == null) {
updater = AtomicIntegerFieldUpdater.newUpdater(AbstractReferenceCountedByteBuf.class, "refCnt");
}

View file

@ -20,7 +20,6 @@ import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicInteger;
import common.net.util.concurrent.FastThreadLocal;
import common.net.util.internal.PlatformDependent;
import common.net.util.internal.SystemPropertyUtil;
import common.net.util.internal.logging.InternalLogger;
import common.net.util.internal.logging.InternalLoggerFactory;
@ -78,7 +77,7 @@ public class PooledByteBufAllocator extends AbstractByteBufAllocator {
"game.net.allocator.numDirectArenas",
(int) Math.min(
runtime.availableProcessors(),
PlatformDependent.maxDirectMemory() / defaultChunkSize / 2 / 3)));
Runtime.getRuntime().maxMemory() / defaultChunkSize / 2 / 3)));
// cache sizes
DEFAULT_TINY_CACHE_SIZE = SystemPropertyUtil.getInt("game.net.allocator.tinyCacheSize", 512);

View file

@ -16,7 +16,6 @@
package common.net.channel;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.NotYetConnectedException;
@ -27,11 +26,9 @@ import common.net.util.DefaultAttributeMap;
import common.net.util.ReferenceCountUtil;
import common.net.util.internal.EmptyArrays;
import common.net.util.internal.OneTimeTask;
import common.net.util.internal.PlatformDependent;
import common.net.util.internal.ThreadLocalRandom;
import common.net.util.internal.logging.InternalLogger;
import common.net.util.internal.logging.InternalLoggerFactory;
import common.util.Util;
/**
* A skeletal {@link Channel} implementation.
@ -458,19 +455,6 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
return;
}
// See: https://github.com/netty/netty/issues/576
if (!Util.WINDOWS && !PlatformDependent.isRoot() &&
Boolean.TRUE.equals(config().getOption(ChannelOption.SO_BROADCAST)) &&
localAddress instanceof InetSocketAddress &&
!((InetSocketAddress) localAddress).getAddress().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.
logger.warn(
"A non-root user can't receive a broadcast packet if the socket " +
"is not bound to a wildcard address; binding to a non-wildcard " +
"address (" + localAddress + ") anyway as requested.");
}
boolean wasActive = isActive();
try {
doBind(localAddress);

View file

@ -17,11 +17,11 @@ package common.net.channel;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import common.net.buffer.ByteBufAllocator;
import common.net.util.UniqueName;
import common.net.util.internal.PlatformDependent;
/**
* A {@link ChannelOption} allows to configure a {@link ChannelConfig} in a type-safe
@ -34,7 +34,7 @@ import common.net.util.internal.PlatformDependent;
public class ChannelOption<T> extends UniqueName {
private static final ConcurrentMap<String, Boolean> names = PlatformDependent.newConcurrentHashMap();
private static final ConcurrentMap<String, Boolean> names = new ConcurrentHashMap<String, Boolean>();
public static final ChannelOption<ByteBufAllocator> ALLOCATOR = valueOf("ALLOCATOR");
public static final ChannelOption<RecvByteBufAllocator> RCVBUF_ALLOCATOR = valueOf("RCVBUF_ALLOCATOR");

View file

@ -27,7 +27,6 @@ import common.net.util.ReferenceCountUtil;
import common.net.util.Recycler.Handle;
import common.net.util.concurrent.FastThreadLocal;
import common.net.util.internal.InternalThreadLocalMap;
import common.net.util.internal.PlatformDependent;
import common.net.util.internal.logging.InternalLogger;
import common.net.util.internal.logging.InternalLoggerFactory;
@ -78,14 +77,14 @@ public final class ChannelOutboundBuffer {
static {
AtomicIntegerFieldUpdater<ChannelOutboundBuffer> writableUpdater =
PlatformDependent.newAtomicIntegerFieldUpdater(ChannelOutboundBuffer.class, "writable");
null;
if (writableUpdater == null) {
writableUpdater = AtomicIntegerFieldUpdater.newUpdater(ChannelOutboundBuffer.class, "writable");
}
WRITABLE_UPDATER = writableUpdater;
AtomicLongFieldUpdater<ChannelOutboundBuffer> pendingSizeUpdater =
PlatformDependent.newAtomicLongFieldUpdater(ChannelOutboundBuffer.class, "totalPendingSize");
null;
if (pendingSizeUpdater == null) {
pendingSizeUpdater = AtomicLongFieldUpdater.newUpdater(ChannelOutboundBuffer.class, "totalPendingSize");
}

View file

@ -32,10 +32,10 @@ import common.net.channel.Channel.Unsafe;
import common.net.util.ReferenceCountUtil;
import common.net.util.concurrent.EventExecutor;
import common.net.util.concurrent.EventExecutorGroup;
import common.net.util.internal.PlatformDependent;
import common.net.util.internal.StringUtil;
import common.net.util.internal.logging.InternalLogger;
import common.net.util.internal.logging.InternalLoggerFactory;
import common.util.Util;
/**
* The default {@link ChannelPipeline} implementation. It is usually created
@ -551,7 +551,7 @@ final class DefaultChannelPipeline implements ChannelPipeline {
future.get();
} catch (ExecutionException ex) {
// In the arbitrary case, we can throw Error, RuntimeException, and Exception
PlatformDependent.throwException(ex.getCause());
Util.throwUnchecked(ex.getCause());
} catch (InterruptedException ex) {
// Interrupt the calling thread (note that this method is not called from the event loop)
Thread.currentThread().interrupt();

View file

@ -16,7 +16,7 @@
package common.net.channel;
import common.net.util.concurrent.EventExecutor;
import common.net.util.internal.PlatformDependent;
import common.util.Util;
/**
* The {@link CompleteChannelFuture} which is failed already. It is
@ -53,13 +53,13 @@ final class FailedChannelFuture extends CompleteChannelFuture {
@Override
public ChannelFuture sync() {
PlatformDependent.throwException(cause);
Util.throwUnchecked(cause);
return this;
}
@Override
public ChannelFuture syncUninterruptibly() {
PlatformDependent.throwException(cause);
Util.throwUnchecked(cause);
return this;
}
}

View file

@ -16,16 +16,16 @@
package common.net.channel.local;
import java.net.SocketAddress;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import common.net.channel.Channel;
import common.net.channel.ChannelException;
import common.net.util.internal.PlatformDependent;
import common.net.util.internal.StringUtil;
final class LocalChannelRegistry {
private static final ConcurrentMap<LocalAddress, Channel> boundChannels = PlatformDependent.newConcurrentHashMap();
private static final ConcurrentMap<LocalAddress, Channel> boundChannels = new ConcurrentHashMap<LocalAddress, Channel>();
static LocalAddress register(
Channel channel, LocalAddress oldLocalAddress, SocketAddress localAddress) {

View file

@ -37,7 +37,7 @@ import common.net.channel.ChannelException;
import common.net.channel.EventLoopException;
import common.net.channel.SingleThreadEventLoop;
import common.net.channel.nio.AbstractNioChannel.NioUnsafe;
import common.net.util.internal.PlatformDependent;
import common.net.util.internal.MpscLinkedQueue;
import common.net.util.internal.SystemPropertyUtil;
import common.net.util.internal.logging.InternalLogger;
import common.net.util.internal.logging.InternalLoggerFactory;
@ -164,7 +164,7 @@ public final class NioEventLoop extends SingleThreadEventLoop {
@Override
protected Queue<Runnable> newTaskQueue() {
// This event loop never calls takeTask()
return PlatformDependent.newMpscQueue();
return new MpscLinkedQueue<Runnable>();
}
/**

View file

@ -15,10 +15,9 @@
*/
package common.net.util;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import common.net.util.internal.PlatformDependent;
/**
* Key which can be used to access {@link Attribute} out of the {@link AttributeMap}. Be aware that it is not be
* possible to have multiple keys with the same name.
@ -29,7 +28,7 @@ import common.net.util.internal.PlatformDependent;
// 'T' is used only at compile time
public final class AttributeKey<T> extends UniqueName {
private static final ConcurrentMap<String, Boolean> names = PlatformDependent.newConcurrentHashMap();
private static final ConcurrentMap<String, Boolean> names = new ConcurrentHashMap<String, Boolean>();
/**
* Creates a new {@link AttributeKey} with the specified {@code name}.

View file

@ -19,8 +19,6 @@ import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import common.net.util.internal.PlatformDependent;
/**
* Default {@link AttributeMap} implementation which use simple synchronization per bucket to keep the memory overhead
* as low as possible.
@ -33,7 +31,7 @@ public class DefaultAttributeMap implements AttributeMap {
static {
AtomicReferenceFieldUpdater<DefaultAttributeMap, AtomicReferenceArray> referenceFieldUpdater =
PlatformDependent.newAtomicReferenceFieldUpdater(DefaultAttributeMap.class, "attributes");
null;
if (referenceFieldUpdater == null) {
referenceFieldUpdater = AtomicReferenceFieldUpdater
.newUpdater(DefaultAttributeMap.class, AtomicReferenceArray.class, "attributes");

View file

@ -28,7 +28,6 @@ import java.util.Enumeration;
import java.util.List;
import java.util.StringTokenizer;
import common.net.util.internal.PlatformDependent;
import common.net.util.internal.logging.InternalLogger;
import common.net.util.internal.logging.InternalLoggerFactory;
import common.util.Util;
@ -84,7 +83,7 @@ public final class NetUtil {
localhost4 = (Inet4Address) InetAddress.getByAddress(LOCALHOST4_BYTES);
} catch (Exception e) {
// We should not get here as long as the length of the address is correct.
PlatformDependent.throwException(e);
Util.throwUnchecked(e);
}
LOCALHOST4 = localhost4;
@ -94,7 +93,7 @@ public final class NetUtil {
localhost6 = (Inet6Address) InetAddress.getByAddress(LOCALHOST6_BYTES);
} catch (Exception e) {
// We should not get here as long as the length of the address is correct.
PlatformDependent.throwException(e);
Util.throwUnchecked(e);
}
LOCALHOST6 = localhost6;

View file

@ -24,10 +24,10 @@ import java.lang.ref.ReferenceQueue;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.EnumSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
import common.net.util.internal.PlatformDependent;
import common.net.util.internal.SystemPropertyUtil;
import common.net.util.internal.logging.InternalLogger;
import common.net.util.internal.logging.InternalLoggerFactory;
@ -124,7 +124,7 @@ public final class ResourceLeakDetector<T> {
private final DefaultResourceLeak tail = new DefaultResourceLeak(null);
private final ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
private final ConcurrentMap<String, Boolean> reportedLeaks = PlatformDependent.newConcurrentHashMap();
private final ConcurrentMap<String, Boolean> reportedLeaks = new ConcurrentHashMap<String, Boolean>();
private final String resourceType;
private final int samplingInterval;

View file

@ -16,10 +16,9 @@
package common.net.util;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import common.net.util.internal.PlatformDependent;
/**
* A special {@link Error} which is used to signal some state or request by throwing it.
* {@link Signal} has an empty stack trace and has no cause to save the instantiation overhead.
@ -28,7 +27,7 @@ public final class Signal extends Error {
private static final long serialVersionUID = -221145131122459977L;
private static final ConcurrentMap<String, Boolean> map = PlatformDependent.newConcurrentHashMap();
private static final ConcurrentMap<String, Boolean> map = new ConcurrentHashMap<String, Boolean>();
private final UniqueName uname;

View file

@ -24,8 +24,8 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import common.net.util.concurrent.DefaultThreadFactory;
import common.net.util.internal.MpscLinkedQueue;
import common.net.util.internal.MpscLinkedQueueNode;
import common.net.util.internal.PlatformDependent;
import common.net.util.internal.logging.InternalLogger;
import common.net.util.internal.logging.InternalLoggerFactory;
@ -43,7 +43,7 @@ public final class ThreadDeathWatcher {
private static final ThreadFactory threadFactory =
new DefaultThreadFactory(ThreadDeathWatcher.class, true, Thread.MIN_PRIORITY);
private static final Queue<Entry> pendingEntries = PlatformDependent.newMpscQueue();
private static final Queue<Entry> pendingEntries = new MpscLinkedQueue<Entry>();
private static final Watcher watcher = new Watcher();
private static final AtomicBoolean started = new AtomicBoolean();
private static volatile Thread watcherThread;

View file

@ -24,10 +24,10 @@ import java.util.concurrent.TimeUnit;
import common.net.util.Signal;
import common.net.util.internal.EmptyArrays;
import common.net.util.internal.InternalThreadLocalMap;
import common.net.util.internal.PlatformDependent;
import common.net.util.internal.StringUtil;
import common.net.util.internal.logging.InternalLogger;
import common.net.util.internal.logging.InternalLoggerFactory;
import common.util.Util;
public class DefaultPromise<V> extends AbstractFuture<V> implements Promise<V> {
@ -233,7 +233,7 @@ public class DefaultPromise<V> extends AbstractFuture<V> implements Promise<V> {
return;
}
PlatformDependent.throwException(cause);
Util.throwUnchecked(cause);
}
@Override

View file

@ -15,7 +15,7 @@
*/
package common.net.util.concurrent;
import common.net.util.internal.PlatformDependent;
import common.util.Util;
/**
* The {@link CompleteFuture} which is failed already. It is
@ -52,13 +52,13 @@ public final class FailedFuture<V> extends CompleteFuture<V> {
@Override
public Future<V> sync() {
PlatformDependent.throwException(cause);
Util.throwUnchecked(cause);
return this;
}
@Override
public Future<V> syncUninterruptibly() {
PlatformDependent.throwException(cause);
Util.throwUnchecked(cause);
return this;
}

View file

@ -20,7 +20,7 @@ import java.util.IdentityHashMap;
import java.util.Set;
import common.net.util.internal.InternalThreadLocalMap;
import common.net.util.internal.PlatformDependent;
import common.util.Util;
/**
* A special variant of {@link ThreadLocal} that yields higher access performan when accessed from a
@ -154,7 +154,7 @@ public class FastThreadLocal<V> {
try {
v = initialValue();
} catch (Exception e) {
PlatformDependent.throwException(e);
Util.throwUnchecked(e);
}
threadLocalMap.setIndexedVariable(index, v);
@ -225,7 +225,7 @@ public class FastThreadLocal<V> {
try {
onRemoval((V) v);
} catch (Exception e) {
PlatformDependent.throwException(e);
Util.throwUnchecked(e);
}
}
}

View file

@ -32,7 +32,6 @@ import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import common.net.util.internal.PlatformDependent;
import common.net.util.internal.logging.InternalLogger;
import common.net.util.internal.logging.InternalLoggerFactory;
@ -62,7 +61,7 @@ public abstract class SingleThreadEventExecutor extends AbstractEventExecutor {
static {
AtomicIntegerFieldUpdater<SingleThreadEventExecutor> updater =
PlatformDependent.newAtomicIntegerFieldUpdater(SingleThreadEventExecutor.class, "state");
null;
if (updater == null) {
updater = AtomicIntegerFieldUpdater.newUpdater(SingleThreadEventExecutor.class, "state");
}

View file

@ -65,7 +65,7 @@ import java.util.Queue;
* data structure modified to avoid false sharing between head and tail Ref as per implementation of MpscLinkedQueue
* on <a href="https://github.com/JCTools/JCTools">JCTools project</a>.
*/
final class MpscLinkedQueue<E> extends MpscLinkedQueueTailRef<E> implements Queue<E> {
public final class MpscLinkedQueue<E> extends MpscLinkedQueueTailRef<E> implements Queue<E> {
private static final long serialVersionUID = -1878402552271506449L;
@ -87,7 +87,7 @@ final class MpscLinkedQueue<E> extends MpscLinkedQueueTailRef<E> implements Queu
//
// Also note that this class extends AtomicReference for the "tail" slot (which is the one that is appended to)
// since Unsafe does not expose XCHG operation intrinsically.
MpscLinkedQueue() {
public MpscLinkedQueue() {
MpscLinkedQueueNode<E> tombstone = new DefaultNode<E>(null);
setHeadRef(tombstone);
setTailRef(tombstone);

View file

@ -30,7 +30,7 @@ abstract class MpscLinkedQueueHeadRef<E> extends MpscLinkedQueuePad0<E> implemen
static {
AtomicReferenceFieldUpdater<MpscLinkedQueueHeadRef, MpscLinkedQueueNode> updater;
updater = PlatformDependent.newAtomicReferenceFieldUpdater(MpscLinkedQueueHeadRef.class, "headRef");
updater = null;
if (updater == null) {
updater = AtomicReferenceFieldUpdater.newUpdater(
MpscLinkedQueueHeadRef.class, MpscLinkedQueueNode.class, "headRef");

View file

@ -27,7 +27,7 @@ public abstract class MpscLinkedQueueNode<T> {
AtomicReferenceFieldUpdater<MpscLinkedQueueNode, MpscLinkedQueueNode> u;
u = PlatformDependent.newAtomicReferenceFieldUpdater(MpscLinkedQueueNode.class, "next");
u = null;
if (u == null) {
u = AtomicReferenceFieldUpdater.newUpdater(MpscLinkedQueueNode.class, MpscLinkedQueueNode.class, "next");
}

View file

@ -28,7 +28,7 @@ abstract class MpscLinkedQueueTailRef<E> extends MpscLinkedQueuePad1<E> {
static {
AtomicReferenceFieldUpdater<MpscLinkedQueueTailRef, MpscLinkedQueueNode> updater;
updater = PlatformDependent.newAtomicReferenceFieldUpdater(MpscLinkedQueueTailRef.class, "tailRef");
updater = null;
if (updater == null) {
updater = AtomicReferenceFieldUpdater.newUpdater(
MpscLinkedQueueTailRef.class, MpscLinkedQueueNode.class, "tailRef");

View file

@ -1,348 +0,0 @@
/*
* 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 common.net.util.internal;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import common.net.util.CharsetUtil;
import common.net.util.internal.logging.InternalLogger;
import common.net.util.internal.logging.InternalLoggerFactory;
import common.util.Util;
/**
* 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.
* <p>
* You can disable the use of {@code sun.misc.Unsafe} if you specify
* the system property <strong>game.net.noUnsafe</strong>.
*/
public final class PlatformDependent {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(PlatformDependent.class);
private static final Pattern MAX_DIRECT_MEMORY_SIZE_ARG_PATTERN = Pattern.compile(
"\\s*-XX:MaxDirectMemorySize\\s*=\\s*([0-9]+)\\s*([kKmMgG]?)\\s*$");
private static final boolean IS_ROOT = isRoot0();
private static final long MAX_DIRECT_MEMORY = maxDirectMemory0();
/**
* 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;
}
/**
* Returns the maximum memory reserved for direct buffer allocation.
*/
public static long maxDirectMemory() {
return MAX_DIRECT_MEMORY;
}
/**
* Raises an exception bypassing compiler checks for checked exceptions.
*/
public static void throwException(Throwable t) {
PlatformDependent.<RuntimeException>throwException0(t);
}
private static <E extends Throwable> void throwException0(Throwable t) throws E {
throw (E) t;
}
/**
* Creates a new fastest {@link ConcurrentMap} implementaion for the current platform.
*/
public static <K, V> ConcurrentMap<K, V> newConcurrentHashMap() {
// if (CAN_USE_CHM_V8) {
// return new ConcurrentHashMapV8<K, V>();
// } else {
return new ConcurrentHashMap<K, V>();
// }
}
/**
* Creates a new fastest {@link ConcurrentMap} implementaion for the current platform.
*/
public static <K, V> ConcurrentMap<K, V> newConcurrentHashMap(int initialCapacity) {
// if (CAN_USE_CHM_V8) {
// return new ConcurrentHashMapV8<K, V>(initialCapacity);
// } else {
return new ConcurrentHashMap<K, V>(initialCapacity);
// }
}
/**
* Creates a new fastest {@link ConcurrentMap} implementaion for the current platform.
*/
public static <K, V> ConcurrentMap<K, V> newConcurrentHashMap(int initialCapacity, float loadFactor) {
// if (CAN_USE_CHM_V8) {
// return new ConcurrentHashMapV8<K, V>(initialCapacity, loadFactor);
// } else {
return new ConcurrentHashMap<K, V>(initialCapacity, loadFactor);
// }
}
/**
* Creates a new fastest {@link ConcurrentMap} implementaion for the current platform.
*/
public static <K, V> ConcurrentMap<K, V> newConcurrentHashMap(
int initialCapacity, float loadFactor, int concurrencyLevel) {
// if (CAN_USE_CHM_V8) {
// return new ConcurrentHashMapV8<K, V>(initialCapacity, loadFactor, concurrencyLevel);
// } else {
return new ConcurrentHashMap<K, V>(initialCapacity, loadFactor, concurrencyLevel);
// }
}
/**
* Creates a new fastest {@link ConcurrentMap} implementaion for the current platform.
*/
public static <K, V> ConcurrentMap<K, V> newConcurrentHashMap(Map<? extends K, ? extends V> map) {
// if (CAN_USE_CHM_V8) {
// return new ConcurrentHashMapV8<K, V>(map);
// } else {
return new ConcurrentHashMap<K, V>(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) {
}
/**
* Create a new optimized {@link AtomicReferenceFieldUpdater} or {@code null} if it
* could not be created. Because of this the caller need to check for {@code null} and if {@code null} is returned
* use {@link AtomicReferenceFieldUpdater#newUpdater(Class, Class, String)} as fallback.
*/
public static <U, W> AtomicReferenceFieldUpdater<U, W> newAtomicReferenceFieldUpdater(
Class<U> tclass, String fieldName) {
return null;
}
/**
* Create a new optimized {@link AtomicIntegerFieldUpdater} or {@code null} if it
* could not be created. Because of this the caller need to check for {@code null} and if {@code null} is returned
* use {@link AtomicIntegerFieldUpdater#newUpdater(Class, String)} as fallback.
*/
public static <T> AtomicIntegerFieldUpdater<T> newAtomicIntegerFieldUpdater(
Class<?> tclass, String fieldName) {
return null;
}
/**
* Create a new optimized {@link AtomicLongFieldUpdater} or {@code null} if it
* could not be created. Because of this the caller need to check for {@code null} and if {@code null} is returned
* use {@link AtomicLongFieldUpdater#newUpdater(Class, String)} as fallback.
*/
public static <T> AtomicLongFieldUpdater<T> newAtomicLongFieldUpdater(
Class<?> tclass, String fieldName) {
return null;
}
/**
* Create a new {@link Queue} which is safe to use for multiple producers (different threads) and a single
* consumer (one thread!).
*/
public static <T> Queue<T> newMpscQueue() {
return new MpscLinkedQueue<T>();
}
private static boolean isRoot0() {
if (Util.WINDOWS) {
return false;
}
String[] ID_COMMANDS = { "/usr/bin/id", "/bin/id", "id", "/usr/xpg4/bin/id"};
Pattern UID_PATTERN = Pattern.compile("^(?:0|[1-9][0-9]*)$");
for (String idCmd: ID_COMMANDS) {
Process p = null;
BufferedReader in = null;
String uid = null;
try {
p = Runtime.getRuntime().exec(new String[] { idCmd, "-u" });
in = new BufferedReader(new InputStreamReader(p.getInputStream(), CharsetUtil.US_ASCII));
uid = in.readLine();
in.close();
for (;;) {
try {
int exitCode = p.waitFor();
if (exitCode != 0) {
uid = null;
}
break;
} catch (InterruptedException e) {
// Ignore
}
}
} catch (Exception e) {
// Failed to run the command.
uid = null;
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// Ignore
}
}
if (p != null) {
try {
p.destroy();
} catch (Exception e) {
// Android sometimes triggers an ErrnoException.
}
}
}
if (uid != null && UID_PATTERN.matcher(uid).matches()) {
logger.debug("UID: {}", uid);
return "0".equals(uid);
}
}
logger.debug("Could not determine the current UID using /usr/bin/id; attempting to bind at privileged ports.");
Pattern PERMISSION_DENIED = Pattern.compile(".*(?:denied|not.*permitted).*");
for (int i = 1023; i > 0; i --) {
ServerSocket ss = null;
try {
ss = new ServerSocket();
ss.setReuseAddress(true);
ss.bind(new InetSocketAddress(i));
if (logger.isDebugEnabled()) {
logger.debug("UID: 0 (succeded to bind at port {})", i);
}
return true;
} 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.
}
}
}
}
logger.debug("UID: non-root (failed to bind at any privileged ports)");
return false;
}
private static long maxDirectMemory0() {
long maxDirectMemory = 0;
try {
// Try to get from sun.misc.VM.maxDirectMemory() which should be most accurate.
Class<?> vmClass = Class.forName("sun.misc.VM", true, ClassLoader.getSystemClassLoader());
Method m = vmClass.getDeclaredMethod("maxDirectMemory");
maxDirectMemory = ((Number) m.invoke(null)).longValue();
} catch (Throwable t) {
// Ignore
}
if (maxDirectMemory > 0) {
return maxDirectMemory;
}
try {
// Now try to get the JVM option (-XX:MaxDirectMemorySize) and parse it.
// Note that we are using reflection because Android doesn't have these classes.
Class<?> mgmtFactoryClass = Class.forName(
"java.lang.management.ManagementFactory", true, ClassLoader.getSystemClassLoader());
Class<?> runtimeClass = Class.forName(
"java.lang.management.RuntimeMXBean", true, ClassLoader.getSystemClassLoader());
Object runtime = mgmtFactoryClass.getDeclaredMethod("getRuntimeMXBean").invoke(null);
List<String> vmArgs = (List<String>) runtimeClass.getDeclaredMethod("getInputArguments").invoke(runtime);
for (int i = vmArgs.size() - 1; i >= 0; i --) {
Matcher m = MAX_DIRECT_MEMORY_SIZE_ARG_PATTERN.matcher(vmArgs.get(i));
if (!m.matches()) {
continue;
}
maxDirectMemory = Long.parseLong(m.group(1));
switch (m.group(2).charAt(0)) {
case 'k': case 'K':
maxDirectMemory *= 1024;
break;
case 'm': case 'M':
maxDirectMemory *= 1024 * 1024;
break;
case 'g': case 'G':
maxDirectMemory *= 1024 * 1024 * 1024;
break;
}
break;
}
} catch (Throwable t) {
// Ignore
}
if (maxDirectMemory <= 0) {
maxDirectMemory = Runtime.getRuntime().maxMemory();
logger.debug("maxDirectMemory: {} bytes (maybe)", maxDirectMemory);
} else {
logger.debug("maxDirectMemory: {} bytes", maxDirectMemory);
}
return maxDirectMemory;
}
private PlatformDependent() {
// only static method supported
}
}

View file

@ -20,6 +20,8 @@ import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;
import common.util.Util;
/**
* String utility class.
*/
@ -136,7 +138,7 @@ public final class StringUtil {
try {
buf.append(byteToHexStringPadded(value));
} catch (IOException e) {
PlatformDependent.throwException(e);
Util.throwUnchecked(e);
}
return buf;
}
@ -187,7 +189,7 @@ public final class StringUtil {
try {
buf.append(byteToHexString(value));
} catch (IOException e) {
PlatformDependent.throwException(e);
Util.throwUnchecked(e);
}
return buf;
}

View file

@ -488,4 +488,8 @@ int utf_len(const char *str) {
}
return !hyphen;
}
public static void throwUnchecked(Throwable t) {
throw (RuntimeException)t;
}
}