use of io.netty.channel.EventLoop in project netty by netty.
the class AbstractKQueueChannel method clearReadFilter.
final void clearReadFilter() {
// Only clear if registered with an EventLoop as otherwise
if (isRegistered()) {
final EventLoop loop = eventLoop();
final AbstractKQueueUnsafe unsafe = (AbstractKQueueUnsafe) unsafe();
if (loop.inEventLoop()) {
unsafe.clearReadFilter0();
} else {
// schedule a task to clear the EPOLLIN as it is not safe to modify it directly
loop.execute(new Runnable() {
@Override
public void run() {
if (!unsafe.readPending && !config().isAutoRead()) {
// Still no read triggered so clear it now
unsafe.clearReadFilter0();
}
}
});
}
} else {
// The EventLoop is not registered atm so just update the flags so the correct value
// will be used once the channel is registered
readFilterEnabled = false;
}
}
use of io.netty.channel.EventLoop in project netty by netty.
the class EpollEventLoopTest method testScheduleBigDelayNotOverflow.
@Test
public void testScheduleBigDelayNotOverflow() {
final AtomicReference<Throwable> capture = new AtomicReference<Throwable>();
final EventLoopGroup group = new EpollEventLoop(null, new ThreadPerTaskExecutor(new DefaultThreadFactory(getClass())), 0, DefaultSelectStrategyFactory.INSTANCE.newSelectStrategy(), RejectedExecutionHandlers.reject(), null, null) {
@Override
void handleLoopException(Throwable t) {
capture.set(t);
super.handleLoopException(t);
}
};
try {
final EventLoop eventLoop = group.next();
Future<?> future = eventLoop.schedule(new Runnable() {
@Override
public void run() {
// NOOP
}
}, Long.MAX_VALUE, TimeUnit.MILLISECONDS);
assertFalse(future.awaitUninterruptibly(1000));
assertTrue(future.cancel(true));
assertNull(capture.get());
} finally {
group.shutdownGracefully();
}
}
use of io.netty.channel.EventLoop in project netty by netty.
the class KQueueEventLoopTest method testScheduleBigDelayNotOverflow.
@Test
public void testScheduleBigDelayNotOverflow() {
EventLoopGroup group = new KQueueEventLoopGroup(1);
final EventLoop el = group.next();
Future<?> future = el.schedule(new Runnable() {
@Override
public void run() {
// NOOP
}
}, Long.MAX_VALUE, TimeUnit.MILLISECONDS);
assertFalse(future.awaitUninterruptibly(1000));
assertTrue(future.cancel(true));
group.shutdownGracefully();
}
use of io.netty.channel.EventLoop in project netty by netty.
the class FixedChannelPoolMapDeadlockTest method testDeadlockOnAcquire.
@Test
public void testDeadlockOnAcquire() throws Exception {
final EventLoop threadA1 = new DefaultEventLoop();
final Bootstrap bootstrapA1 = new Bootstrap().channel(LocalChannel.class).group(threadA1).localAddress(new LocalAddress("A1"));
final EventLoop threadA2 = new DefaultEventLoop();
final Bootstrap bootstrapA2 = new Bootstrap().channel(LocalChannel.class).group(threadA2).localAddress(new LocalAddress("A2"));
final EventLoop threadB1 = new DefaultEventLoop();
final Bootstrap bootstrapB1 = new Bootstrap().channel(LocalChannel.class).group(threadB1).localAddress(new LocalAddress("B1"));
final EventLoop threadB2 = new DefaultEventLoop();
final Bootstrap bootstrapB2 = new Bootstrap().channel(LocalChannel.class).group(threadB2).localAddress(new LocalAddress("B2"));
final FixedChannelPool poolA1 = new FixedChannelPool(bootstrapA1, NOOP_HANDLER, 1);
final FixedChannelPool poolA2 = new FixedChannelPool(bootstrapB2, NOOP_HANDLER, 1);
final FixedChannelPool poolB1 = new FixedChannelPool(bootstrapB1, NOOP_HANDLER, 1);
final FixedChannelPool poolB2 = new FixedChannelPool(bootstrapA2, NOOP_HANDLER, 1);
// Synchronize threads on these barriers to ensure order of execution, first wait until each thread is inside
// the newPool callback, then hold the two threads that should lose the match until the first two returns, then
// release them to test if they deadlock when trying to release their pools on each other's threads.
final CyclicBarrier arrivalBarrier = new CyclicBarrier(4);
final CyclicBarrier releaseBarrier = new CyclicBarrier(3);
final AbstractChannelPoolMap<String, FixedChannelPool> channelPoolMap = new AbstractChannelPoolMap<String, FixedChannelPool>() {
@Override
protected FixedChannelPool newPool(String key) {
if ("A".equals(key)) {
if (threadA1.inEventLoop()) {
// Thread A1 gets pool A with thread A1
await(arrivalBarrier);
return poolA1;
} else if (threadA2.inEventLoop()) {
// Thread A2 gets pool A with thread B2, but only after A1 won
await(arrivalBarrier);
await(releaseBarrier);
return poolA2;
}
} else if ("B".equals(key)) {
if (threadB1.inEventLoop()) {
// Thread B1 gets pool with thread B1
await(arrivalBarrier);
return poolB1;
} else if (threadB2.inEventLoop()) {
// Thread B2 gets pool with thread A2
await(arrivalBarrier);
await(releaseBarrier);
return poolB2;
}
}
throw new AssertionError("Unexpected key=" + key + " or thread=" + Thread.currentThread().getName());
}
};
// Thread A1 calls ChannelPoolMap.get(A)
// Thread A2 calls ChannelPoolMap.get(A)
// Thread B1 calls ChannelPoolMap.get(B)
// Thread B2 calls ChannelPoolMap.get(B)
Future<FixedChannelPool> futureA1 = threadA1.submit(new Callable<FixedChannelPool>() {
@Override
public FixedChannelPool call() throws Exception {
return channelPoolMap.get("A");
}
});
Future<FixedChannelPool> futureA2 = threadA2.submit(new Callable<FixedChannelPool>() {
@Override
public FixedChannelPool call() throws Exception {
return channelPoolMap.get("A");
}
});
Future<FixedChannelPool> futureB1 = threadB1.submit(new Callable<FixedChannelPool>() {
@Override
public FixedChannelPool call() throws Exception {
return channelPoolMap.get("B");
}
});
Future<FixedChannelPool> futureB2 = threadB2.submit(new Callable<FixedChannelPool>() {
@Override
public FixedChannelPool call() throws Exception {
return channelPoolMap.get("B");
}
});
// These should always succeed and return with new pools
try {
assertSame(poolA1, futureA1.get(1, TimeUnit.SECONDS));
assertSame(poolB1, futureB1.get(1, TimeUnit.SECONDS));
} catch (Exception e) {
shutdown(threadA1, threadA2, threadB1, threadB2);
throw e;
}
// Now release the other two threads which at this point lost the race and will try to clean up the acquired
// pools. The expected scenario is that both pools close, in case of a deadlock they will hang.
await(releaseBarrier);
// If the close is not blocking, then the previously created pools will be returned
try {
assertSame(poolA1, futureA2.get(1, TimeUnit.SECONDS));
assertSame(poolB1, futureB2.get(1, TimeUnit.SECONDS));
} catch (TimeoutException e) {
// Fail the test on timeout to distinguish from other errors
throw new AssertionError(e);
} finally {
poolA1.close();
poolA2.close();
poolB1.close();
poolB2.close();
channelPoolMap.close();
shutdown(threadA1, threadA2, threadB1, threadB2);
}
}
use of io.netty.channel.EventLoop in project netty by netty.
the class AbstractChannelPoolMapTest method testRemoveClosesChannelPool.
@Test
public void testRemoveClosesChannelPool() {
EventLoopGroup group = new LocalEventLoopGroup();
LocalAddress addr = new LocalAddress(getLocalAddrId());
final Bootstrap cb = new Bootstrap();
cb.remoteAddress(addr);
cb.group(group).channel(LocalChannel.class);
AbstractChannelPoolMap<EventLoop, TestPool> poolMap = new AbstractChannelPoolMap<EventLoop, TestPool>() {
@Override
protected TestPool newPool(EventLoop key) {
return new TestPool(cb.clone(key), new TestChannelPoolHandler());
}
};
EventLoop loop = group.next();
TestPool pool = poolMap.get(loop);
assertTrue(poolMap.remove(loop));
// the pool should be closed eventually after remove
pool.closeFuture.awaitUninterruptibly(1, TimeUnit.SECONDS);
assertTrue(pool.closeFuture.isDone());
poolMap.close();
}
Aggregations