netty cleanup
This commit is contained in:
parent
c8e5c16e41
commit
f30141c8f3
27 changed files with 51 additions and 418 deletions
|
@ -26,8 +26,8 @@ import java.nio.charset.Charset;
|
||||||
|
|
||||||
import common.net.util.IllegalReferenceCountException;
|
import common.net.util.IllegalReferenceCountException;
|
||||||
import common.net.util.ResourceLeakDetector;
|
import common.net.util.ResourceLeakDetector;
|
||||||
import common.net.util.internal.PlatformDependent;
|
|
||||||
import common.net.util.internal.StringUtil;
|
import common.net.util.internal.StringUtil;
|
||||||
|
import common.util.Util;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1030,7 +1030,7 @@ public abstract class AbstractByteBuf extends ByteBuf {
|
||||||
}
|
}
|
||||||
} while (i < endIndex);
|
} while (i < endIndex);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
PlatformDependent.throwException(e);
|
Util.throwUnchecked(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1071,7 +1071,7 @@ public abstract class AbstractByteBuf extends ByteBuf {
|
||||||
}
|
}
|
||||||
} while (i >= index);
|
} while (i >= index);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
PlatformDependent.throwException(e);
|
Util.throwUnchecked(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -19,7 +19,6 @@ package common.net.buffer;
|
||||||
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
|
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
|
||||||
|
|
||||||
import common.net.util.IllegalReferenceCountException;
|
import common.net.util.IllegalReferenceCountException;
|
||||||
import common.net.util.internal.PlatformDependent;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class for {@link ByteBuf} implementations that count references.
|
* Abstract base class for {@link ByteBuf} implementations that count references.
|
||||||
|
@ -30,7 +29,7 @@ public abstract class AbstractReferenceCountedByteBuf extends AbstractByteBuf {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
AtomicIntegerFieldUpdater<AbstractReferenceCountedByteBuf> updater =
|
AtomicIntegerFieldUpdater<AbstractReferenceCountedByteBuf> updater =
|
||||||
PlatformDependent.newAtomicIntegerFieldUpdater(AbstractReferenceCountedByteBuf.class, "refCnt");
|
null;
|
||||||
if (updater == null) {
|
if (updater == null) {
|
||||||
updater = AtomicIntegerFieldUpdater.newUpdater(AbstractReferenceCountedByteBuf.class, "refCnt");
|
updater = AtomicIntegerFieldUpdater.newUpdater(AbstractReferenceCountedByteBuf.class, "refCnt");
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@ import java.nio.ByteBuffer;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import common.net.util.concurrent.FastThreadLocal;
|
import common.net.util.concurrent.FastThreadLocal;
|
||||||
import common.net.util.internal.PlatformDependent;
|
|
||||||
import common.net.util.internal.SystemPropertyUtil;
|
import common.net.util.internal.SystemPropertyUtil;
|
||||||
import common.net.util.internal.logging.InternalLogger;
|
import common.net.util.internal.logging.InternalLogger;
|
||||||
import common.net.util.internal.logging.InternalLoggerFactory;
|
import common.net.util.internal.logging.InternalLoggerFactory;
|
||||||
|
@ -78,7 +77,7 @@ public class PooledByteBufAllocator extends AbstractByteBufAllocator {
|
||||||
"game.net.allocator.numDirectArenas",
|
"game.net.allocator.numDirectArenas",
|
||||||
(int) Math.min(
|
(int) Math.min(
|
||||||
runtime.availableProcessors(),
|
runtime.availableProcessors(),
|
||||||
PlatformDependent.maxDirectMemory() / defaultChunkSize / 2 / 3)));
|
Runtime.getRuntime().maxMemory() / defaultChunkSize / 2 / 3)));
|
||||||
|
|
||||||
// cache sizes
|
// cache sizes
|
||||||
DEFAULT_TINY_CACHE_SIZE = SystemPropertyUtil.getInt("game.net.allocator.tinyCacheSize", 512);
|
DEFAULT_TINY_CACHE_SIZE = SystemPropertyUtil.getInt("game.net.allocator.tinyCacheSize", 512);
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
package common.net.channel;
|
package common.net.channel;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.nio.channels.ClosedChannelException;
|
import java.nio.channels.ClosedChannelException;
|
||||||
import java.nio.channels.NotYetConnectedException;
|
import java.nio.channels.NotYetConnectedException;
|
||||||
|
@ -27,11 +26,9 @@ import common.net.util.DefaultAttributeMap;
|
||||||
import common.net.util.ReferenceCountUtil;
|
import common.net.util.ReferenceCountUtil;
|
||||||
import common.net.util.internal.EmptyArrays;
|
import common.net.util.internal.EmptyArrays;
|
||||||
import common.net.util.internal.OneTimeTask;
|
import common.net.util.internal.OneTimeTask;
|
||||||
import common.net.util.internal.PlatformDependent;
|
|
||||||
import common.net.util.internal.ThreadLocalRandom;
|
import common.net.util.internal.ThreadLocalRandom;
|
||||||
import common.net.util.internal.logging.InternalLogger;
|
import common.net.util.internal.logging.InternalLogger;
|
||||||
import common.net.util.internal.logging.InternalLoggerFactory;
|
import common.net.util.internal.logging.InternalLoggerFactory;
|
||||||
import common.util.Util;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A skeletal {@link Channel} implementation.
|
* A skeletal {@link Channel} implementation.
|
||||||
|
@ -458,19 +455,6 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
||||||
return;
|
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();
|
boolean wasActive = isActive();
|
||||||
try {
|
try {
|
||||||
doBind(localAddress);
|
doBind(localAddress);
|
||||||
|
|
|
@ -17,11 +17,11 @@ package common.net.channel;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.NetworkInterface;
|
import java.net.NetworkInterface;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
import common.net.buffer.ByteBufAllocator;
|
import common.net.buffer.ByteBufAllocator;
|
||||||
import common.net.util.UniqueName;
|
import common.net.util.UniqueName;
|
||||||
import common.net.util.internal.PlatformDependent;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link ChannelOption} allows to configure a {@link ChannelConfig} in a type-safe
|
* 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 {
|
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<ByteBufAllocator> ALLOCATOR = valueOf("ALLOCATOR");
|
||||||
public static final ChannelOption<RecvByteBufAllocator> RCVBUF_ALLOCATOR = valueOf("RCVBUF_ALLOCATOR");
|
public static final ChannelOption<RecvByteBufAllocator> RCVBUF_ALLOCATOR = valueOf("RCVBUF_ALLOCATOR");
|
||||||
|
|
|
@ -27,7 +27,6 @@ import common.net.util.ReferenceCountUtil;
|
||||||
import common.net.util.Recycler.Handle;
|
import common.net.util.Recycler.Handle;
|
||||||
import common.net.util.concurrent.FastThreadLocal;
|
import common.net.util.concurrent.FastThreadLocal;
|
||||||
import common.net.util.internal.InternalThreadLocalMap;
|
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.InternalLogger;
|
||||||
import common.net.util.internal.logging.InternalLoggerFactory;
|
import common.net.util.internal.logging.InternalLoggerFactory;
|
||||||
|
|
||||||
|
@ -78,14 +77,14 @@ public final class ChannelOutboundBuffer {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
AtomicIntegerFieldUpdater<ChannelOutboundBuffer> writableUpdater =
|
AtomicIntegerFieldUpdater<ChannelOutboundBuffer> writableUpdater =
|
||||||
PlatformDependent.newAtomicIntegerFieldUpdater(ChannelOutboundBuffer.class, "writable");
|
null;
|
||||||
if (writableUpdater == null) {
|
if (writableUpdater == null) {
|
||||||
writableUpdater = AtomicIntegerFieldUpdater.newUpdater(ChannelOutboundBuffer.class, "writable");
|
writableUpdater = AtomicIntegerFieldUpdater.newUpdater(ChannelOutboundBuffer.class, "writable");
|
||||||
}
|
}
|
||||||
WRITABLE_UPDATER = writableUpdater;
|
WRITABLE_UPDATER = writableUpdater;
|
||||||
|
|
||||||
AtomicLongFieldUpdater<ChannelOutboundBuffer> pendingSizeUpdater =
|
AtomicLongFieldUpdater<ChannelOutboundBuffer> pendingSizeUpdater =
|
||||||
PlatformDependent.newAtomicLongFieldUpdater(ChannelOutboundBuffer.class, "totalPendingSize");
|
null;
|
||||||
if (pendingSizeUpdater == null) {
|
if (pendingSizeUpdater == null) {
|
||||||
pendingSizeUpdater = AtomicLongFieldUpdater.newUpdater(ChannelOutboundBuffer.class, "totalPendingSize");
|
pendingSizeUpdater = AtomicLongFieldUpdater.newUpdater(ChannelOutboundBuffer.class, "totalPendingSize");
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,10 +32,10 @@ import common.net.channel.Channel.Unsafe;
|
||||||
import common.net.util.ReferenceCountUtil;
|
import common.net.util.ReferenceCountUtil;
|
||||||
import common.net.util.concurrent.EventExecutor;
|
import common.net.util.concurrent.EventExecutor;
|
||||||
import common.net.util.concurrent.EventExecutorGroup;
|
import common.net.util.concurrent.EventExecutorGroup;
|
||||||
import common.net.util.internal.PlatformDependent;
|
|
||||||
import common.net.util.internal.StringUtil;
|
import common.net.util.internal.StringUtil;
|
||||||
import common.net.util.internal.logging.InternalLogger;
|
import common.net.util.internal.logging.InternalLogger;
|
||||||
import common.net.util.internal.logging.InternalLoggerFactory;
|
import common.net.util.internal.logging.InternalLoggerFactory;
|
||||||
|
import common.util.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default {@link ChannelPipeline} implementation. It is usually created
|
* The default {@link ChannelPipeline} implementation. It is usually created
|
||||||
|
@ -551,7 +551,7 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
||||||
future.get();
|
future.get();
|
||||||
} catch (ExecutionException ex) {
|
} catch (ExecutionException ex) {
|
||||||
// In the arbitrary case, we can throw Error, RuntimeException, and Exception
|
// In the arbitrary case, we can throw Error, RuntimeException, and Exception
|
||||||
PlatformDependent.throwException(ex.getCause());
|
Util.throwUnchecked(ex.getCause());
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
// Interrupt the calling thread (note that this method is not called from the event loop)
|
// Interrupt the calling thread (note that this method is not called from the event loop)
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
package common.net.channel;
|
package common.net.channel;
|
||||||
|
|
||||||
import common.net.util.concurrent.EventExecutor;
|
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
|
* The {@link CompleteChannelFuture} which is failed already. It is
|
||||||
|
@ -53,13 +53,13 @@ final class FailedChannelFuture extends CompleteChannelFuture {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelFuture sync() {
|
public ChannelFuture sync() {
|
||||||
PlatformDependent.throwException(cause);
|
Util.throwUnchecked(cause);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelFuture syncUninterruptibly() {
|
public ChannelFuture syncUninterruptibly() {
|
||||||
PlatformDependent.throwException(cause);
|
Util.throwUnchecked(cause);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,16 +16,16 @@
|
||||||
package common.net.channel.local;
|
package common.net.channel.local;
|
||||||
|
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
import common.net.channel.Channel;
|
import common.net.channel.Channel;
|
||||||
import common.net.channel.ChannelException;
|
import common.net.channel.ChannelException;
|
||||||
import common.net.util.internal.PlatformDependent;
|
|
||||||
import common.net.util.internal.StringUtil;
|
import common.net.util.internal.StringUtil;
|
||||||
|
|
||||||
final class LocalChannelRegistry {
|
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(
|
static LocalAddress register(
|
||||||
Channel channel, LocalAddress oldLocalAddress, SocketAddress localAddress) {
|
Channel channel, LocalAddress oldLocalAddress, SocketAddress localAddress) {
|
||||||
|
|
|
@ -37,7 +37,7 @@ import common.net.channel.ChannelException;
|
||||||
import common.net.channel.EventLoopException;
|
import common.net.channel.EventLoopException;
|
||||||
import common.net.channel.SingleThreadEventLoop;
|
import common.net.channel.SingleThreadEventLoop;
|
||||||
import common.net.channel.nio.AbstractNioChannel.NioUnsafe;
|
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.SystemPropertyUtil;
|
||||||
import common.net.util.internal.logging.InternalLogger;
|
import common.net.util.internal.logging.InternalLogger;
|
||||||
import common.net.util.internal.logging.InternalLoggerFactory;
|
import common.net.util.internal.logging.InternalLoggerFactory;
|
||||||
|
@ -164,7 +164,7 @@ public final class NioEventLoop extends SingleThreadEventLoop {
|
||||||
@Override
|
@Override
|
||||||
protected Queue<Runnable> newTaskQueue() {
|
protected Queue<Runnable> newTaskQueue() {
|
||||||
// This event loop never calls takeTask()
|
// This event loop never calls takeTask()
|
||||||
return PlatformDependent.newMpscQueue();
|
return new MpscLinkedQueue<Runnable>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -15,10 +15,9 @@
|
||||||
*/
|
*/
|
||||||
package common.net.util;
|
package common.net.util;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
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
|
* 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.
|
* 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
|
// 'T' is used only at compile time
|
||||||
public final class AttributeKey<T> extends UniqueName {
|
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}.
|
* Creates a new {@link AttributeKey} with the specified {@code name}.
|
||||||
|
|
|
@ -19,8 +19,6 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||||
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
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
|
* Default {@link AttributeMap} implementation which use simple synchronization per bucket to keep the memory overhead
|
||||||
* as low as possible.
|
* as low as possible.
|
||||||
|
@ -33,7 +31,7 @@ public class DefaultAttributeMap implements AttributeMap {
|
||||||
static {
|
static {
|
||||||
|
|
||||||
AtomicReferenceFieldUpdater<DefaultAttributeMap, AtomicReferenceArray> referenceFieldUpdater =
|
AtomicReferenceFieldUpdater<DefaultAttributeMap, AtomicReferenceArray> referenceFieldUpdater =
|
||||||
PlatformDependent.newAtomicReferenceFieldUpdater(DefaultAttributeMap.class, "attributes");
|
null;
|
||||||
if (referenceFieldUpdater == null) {
|
if (referenceFieldUpdater == null) {
|
||||||
referenceFieldUpdater = AtomicReferenceFieldUpdater
|
referenceFieldUpdater = AtomicReferenceFieldUpdater
|
||||||
.newUpdater(DefaultAttributeMap.class, AtomicReferenceArray.class, "attributes");
|
.newUpdater(DefaultAttributeMap.class, AtomicReferenceArray.class, "attributes");
|
||||||
|
|
|
@ -28,7 +28,6 @@ import java.util.Enumeration;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
import common.net.util.internal.PlatformDependent;
|
|
||||||
import common.net.util.internal.logging.InternalLogger;
|
import common.net.util.internal.logging.InternalLogger;
|
||||||
import common.net.util.internal.logging.InternalLoggerFactory;
|
import common.net.util.internal.logging.InternalLoggerFactory;
|
||||||
import common.util.Util;
|
import common.util.Util;
|
||||||
|
@ -84,7 +83,7 @@ public final class NetUtil {
|
||||||
localhost4 = (Inet4Address) InetAddress.getByAddress(LOCALHOST4_BYTES);
|
localhost4 = (Inet4Address) InetAddress.getByAddress(LOCALHOST4_BYTES);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// We should not get here as long as the length of the address is correct.
|
// We should not get here as long as the length of the address is correct.
|
||||||
PlatformDependent.throwException(e);
|
Util.throwUnchecked(e);
|
||||||
}
|
}
|
||||||
LOCALHOST4 = localhost4;
|
LOCALHOST4 = localhost4;
|
||||||
|
|
||||||
|
@ -94,7 +93,7 @@ public final class NetUtil {
|
||||||
localhost6 = (Inet6Address) InetAddress.getByAddress(LOCALHOST6_BYTES);
|
localhost6 = (Inet6Address) InetAddress.getByAddress(LOCALHOST6_BYTES);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// We should not get here as long as the length of the address is correct.
|
// We should not get here as long as the length of the address is correct.
|
||||||
PlatformDependent.throwException(e);
|
Util.throwUnchecked(e);
|
||||||
}
|
}
|
||||||
LOCALHOST6 = localhost6;
|
LOCALHOST6 = localhost6;
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,10 @@ import java.lang.ref.ReferenceQueue;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import common.net.util.internal.PlatformDependent;
|
|
||||||
import common.net.util.internal.SystemPropertyUtil;
|
import common.net.util.internal.SystemPropertyUtil;
|
||||||
import common.net.util.internal.logging.InternalLogger;
|
import common.net.util.internal.logging.InternalLogger;
|
||||||
import common.net.util.internal.logging.InternalLoggerFactory;
|
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 DefaultResourceLeak tail = new DefaultResourceLeak(null);
|
||||||
|
|
||||||
private final ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
|
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 String resourceType;
|
||||||
private final int samplingInterval;
|
private final int samplingInterval;
|
||||||
|
|
|
@ -16,10 +16,9 @@
|
||||||
package common.net.util;
|
package common.net.util;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
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.
|
* 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.
|
* {@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 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;
|
private final UniqueName uname;
|
||||||
|
|
|
@ -24,8 +24,8 @@ import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import common.net.util.concurrent.DefaultThreadFactory;
|
import common.net.util.concurrent.DefaultThreadFactory;
|
||||||
|
import common.net.util.internal.MpscLinkedQueue;
|
||||||
import common.net.util.internal.MpscLinkedQueueNode;
|
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.InternalLogger;
|
||||||
import common.net.util.internal.logging.InternalLoggerFactory;
|
import common.net.util.internal.logging.InternalLoggerFactory;
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ public final class ThreadDeathWatcher {
|
||||||
private static final ThreadFactory threadFactory =
|
private static final ThreadFactory threadFactory =
|
||||||
new DefaultThreadFactory(ThreadDeathWatcher.class, true, Thread.MIN_PRIORITY);
|
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 Watcher watcher = new Watcher();
|
||||||
private static final AtomicBoolean started = new AtomicBoolean();
|
private static final AtomicBoolean started = new AtomicBoolean();
|
||||||
private static volatile Thread watcherThread;
|
private static volatile Thread watcherThread;
|
||||||
|
|
|
@ -24,10 +24,10 @@ import java.util.concurrent.TimeUnit;
|
||||||
import common.net.util.Signal;
|
import common.net.util.Signal;
|
||||||
import common.net.util.internal.EmptyArrays;
|
import common.net.util.internal.EmptyArrays;
|
||||||
import common.net.util.internal.InternalThreadLocalMap;
|
import common.net.util.internal.InternalThreadLocalMap;
|
||||||
import common.net.util.internal.PlatformDependent;
|
|
||||||
import common.net.util.internal.StringUtil;
|
import common.net.util.internal.StringUtil;
|
||||||
import common.net.util.internal.logging.InternalLogger;
|
import common.net.util.internal.logging.InternalLogger;
|
||||||
import common.net.util.internal.logging.InternalLoggerFactory;
|
import common.net.util.internal.logging.InternalLoggerFactory;
|
||||||
|
import common.util.Util;
|
||||||
|
|
||||||
public class DefaultPromise<V> extends AbstractFuture<V> implements Promise<V> {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlatformDependent.throwException(cause);
|
Util.throwUnchecked(cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package common.net.util.concurrent;
|
package common.net.util.concurrent;
|
||||||
|
|
||||||
import common.net.util.internal.PlatformDependent;
|
import common.util.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link CompleteFuture} which is failed already. It is
|
* The {@link CompleteFuture} which is failed already. It is
|
||||||
|
@ -52,13 +52,13 @@ public final class FailedFuture<V> extends CompleteFuture<V> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Future<V> sync() {
|
public Future<V> sync() {
|
||||||
PlatformDependent.throwException(cause);
|
Util.throwUnchecked(cause);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Future<V> syncUninterruptibly() {
|
public Future<V> syncUninterruptibly() {
|
||||||
PlatformDependent.throwException(cause);
|
Util.throwUnchecked(cause);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ import java.util.IdentityHashMap;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import common.net.util.internal.InternalThreadLocalMap;
|
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
|
* A special variant of {@link ThreadLocal} that yields higher access performan when accessed from a
|
||||||
|
@ -154,7 +154,7 @@ public class FastThreadLocal<V> {
|
||||||
try {
|
try {
|
||||||
v = initialValue();
|
v = initialValue();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
PlatformDependent.throwException(e);
|
Util.throwUnchecked(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
threadLocalMap.setIndexedVariable(index, v);
|
threadLocalMap.setIndexedVariable(index, v);
|
||||||
|
@ -225,7 +225,7 @@ public class FastThreadLocal<V> {
|
||||||
try {
|
try {
|
||||||
onRemoval((V) v);
|
onRemoval((V) v);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
PlatformDependent.throwException(e);
|
Util.throwUnchecked(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
|
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.InternalLogger;
|
||||||
import common.net.util.internal.logging.InternalLoggerFactory;
|
import common.net.util.internal.logging.InternalLoggerFactory;
|
||||||
|
|
||||||
|
@ -62,7 +61,7 @@ public abstract class SingleThreadEventExecutor extends AbstractEventExecutor {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
AtomicIntegerFieldUpdater<SingleThreadEventExecutor> updater =
|
AtomicIntegerFieldUpdater<SingleThreadEventExecutor> updater =
|
||||||
PlatformDependent.newAtomicIntegerFieldUpdater(SingleThreadEventExecutor.class, "state");
|
null;
|
||||||
if (updater == null) {
|
if (updater == null) {
|
||||||
updater = AtomicIntegerFieldUpdater.newUpdater(SingleThreadEventExecutor.class, "state");
|
updater = AtomicIntegerFieldUpdater.newUpdater(SingleThreadEventExecutor.class, "state");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
* 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>.
|
* 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;
|
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)
|
// 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.
|
// since Unsafe does not expose XCHG operation intrinsically.
|
||||||
MpscLinkedQueue() {
|
public MpscLinkedQueue() {
|
||||||
MpscLinkedQueueNode<E> tombstone = new DefaultNode<E>(null);
|
MpscLinkedQueueNode<E> tombstone = new DefaultNode<E>(null);
|
||||||
setHeadRef(tombstone);
|
setHeadRef(tombstone);
|
||||||
setTailRef(tombstone);
|
setTailRef(tombstone);
|
||||||
|
|
|
@ -30,7 +30,7 @@ abstract class MpscLinkedQueueHeadRef<E> extends MpscLinkedQueuePad0<E> implemen
|
||||||
static {
|
static {
|
||||||
|
|
||||||
AtomicReferenceFieldUpdater<MpscLinkedQueueHeadRef, MpscLinkedQueueNode> updater;
|
AtomicReferenceFieldUpdater<MpscLinkedQueueHeadRef, MpscLinkedQueueNode> updater;
|
||||||
updater = PlatformDependent.newAtomicReferenceFieldUpdater(MpscLinkedQueueHeadRef.class, "headRef");
|
updater = null;
|
||||||
if (updater == null) {
|
if (updater == null) {
|
||||||
updater = AtomicReferenceFieldUpdater.newUpdater(
|
updater = AtomicReferenceFieldUpdater.newUpdater(
|
||||||
MpscLinkedQueueHeadRef.class, MpscLinkedQueueNode.class, "headRef");
|
MpscLinkedQueueHeadRef.class, MpscLinkedQueueNode.class, "headRef");
|
||||||
|
|
|
@ -27,7 +27,7 @@ public abstract class MpscLinkedQueueNode<T> {
|
||||||
|
|
||||||
AtomicReferenceFieldUpdater<MpscLinkedQueueNode, MpscLinkedQueueNode> u;
|
AtomicReferenceFieldUpdater<MpscLinkedQueueNode, MpscLinkedQueueNode> u;
|
||||||
|
|
||||||
u = PlatformDependent.newAtomicReferenceFieldUpdater(MpscLinkedQueueNode.class, "next");
|
u = null;
|
||||||
if (u == null) {
|
if (u == null) {
|
||||||
u = AtomicReferenceFieldUpdater.newUpdater(MpscLinkedQueueNode.class, MpscLinkedQueueNode.class, "next");
|
u = AtomicReferenceFieldUpdater.newUpdater(MpscLinkedQueueNode.class, MpscLinkedQueueNode.class, "next");
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ abstract class MpscLinkedQueueTailRef<E> extends MpscLinkedQueuePad1<E> {
|
||||||
static {
|
static {
|
||||||
|
|
||||||
AtomicReferenceFieldUpdater<MpscLinkedQueueTailRef, MpscLinkedQueueNode> updater;
|
AtomicReferenceFieldUpdater<MpscLinkedQueueTailRef, MpscLinkedQueueNode> updater;
|
||||||
updater = PlatformDependent.newAtomicReferenceFieldUpdater(MpscLinkedQueueTailRef.class, "tailRef");
|
updater = null;
|
||||||
if (updater == null) {
|
if (updater == null) {
|
||||||
updater = AtomicReferenceFieldUpdater.newUpdater(
|
updater = AtomicReferenceFieldUpdater.newUpdater(
|
||||||
MpscLinkedQueueTailRef.class, MpscLinkedQueueNode.class, "tailRef");
|
MpscLinkedQueueTailRef.class, MpscLinkedQueueNode.class, "tailRef");
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -20,6 +20,8 @@ import java.util.ArrayList;
|
||||||
import java.util.Formatter;
|
import java.util.Formatter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import common.util.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* String utility class.
|
* String utility class.
|
||||||
*/
|
*/
|
||||||
|
@ -136,7 +138,7 @@ public final class StringUtil {
|
||||||
try {
|
try {
|
||||||
buf.append(byteToHexStringPadded(value));
|
buf.append(byteToHexStringPadded(value));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
PlatformDependent.throwException(e);
|
Util.throwUnchecked(e);
|
||||||
}
|
}
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
@ -187,7 +189,7 @@ public final class StringUtil {
|
||||||
try {
|
try {
|
||||||
buf.append(byteToHexString(value));
|
buf.append(byteToHexString(value));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
PlatformDependent.throwException(e);
|
Util.throwUnchecked(e);
|
||||||
}
|
}
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -488,4 +488,8 @@ int utf_len(const char *str) {
|
||||||
}
|
}
|
||||||
return !hyphen;
|
return !hyphen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void throwUnchecked(Throwable t) {
|
||||||
|
throw (RuntimeException)t;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue