Example usage for io.netty.channel EventLoop inEventLoop

List of usage examples for io.netty.channel EventLoop inEventLoop

Introduction

In this page you can find the example usage for io.netty.channel EventLoop inEventLoop.

Prototype

boolean inEventLoop();

Source Link

Document

Calls #inEventLoop(Thread) with Thread#currentThread() as argument

Usage

From source file:io.hekate.network.netty.NettyUtilsTest.java

License:Apache License

@Test
public void testRunAtAllCost() throws Exception {
    EventLoop eventLoop = new DefaultEventLoop();

    try {//from  w ww.  java 2  s  .com
        // Check execution on event loop thread.
        Exchanger<Boolean> exchanger = new Exchanger<>();

        NettyUtils.runAtAllCost(eventLoop, () -> {
            try {
                exchanger.exchange(eventLoop.inEventLoop());
            } catch (InterruptedException e) {
                // No-op.
            }
        });

        assertTrue(exchanger.exchange(null));

        // Check execution on fallback thread if event loop is terminated.
        NettyUtils.shutdown(eventLoop).awaitUninterruptedly();

        NettyUtils.runAtAllCost(eventLoop, () -> {
            try {
                exchanger.exchange(eventLoop.inEventLoop());
            } catch (InterruptedException e) {
                // No-op.
            }
        });

        assertFalse(exchanger.exchange(null));
    } finally {
        NettyUtils.shutdown(eventLoop).awaitUninterruptedly();
    }
}

From source file:org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnection.java

License:Apache License

public void close() {
    if (closed) {
        return;/*from  w  w w  .  j  a va 2  s .c om*/
    }

    final SslHandler sslHandler = (SslHandler) channel.pipeline().get("ssl");
    EventLoop eventLoop = channel.eventLoop();
    boolean inEventLoop = eventLoop.inEventLoop();
    //if we are in an event loop we need to close the channel after the writes have finished
    if (!inEventLoop) {
        closeSSLAndChannel(sslHandler, channel);
    } else {
        eventLoop.execute(new Runnable() {
            @Override
            public void run() {
                closeSSLAndChannel(sslHandler, channel);
            }
        });
    }

    closed = true;

    listener.connectionDestroyed(getID());
}

From source file:org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnection.java

License:Apache License

public void write(ActiveMQBuffer buffer, final boolean flush, final boolean batched,
        final ChannelFutureListener futureListener) {

    try {/*from www .  j  ava2  s . co m*/
        writeLock.acquire();

        try {
            if (batchBuffer == null && batchingEnabled && batched && !flush) {
                // Lazily create batch buffer

                batchBuffer = ActiveMQBuffers.dynamicBuffer(BATCHING_BUFFER_SIZE);
            }

            if (batchBuffer != null) {
                batchBuffer.writeBytes(buffer, 0, buffer.writerIndex());

                if (batchBuffer.writerIndex() >= BATCHING_BUFFER_SIZE || !batched || flush) {
                    // If the batch buffer is full or it's flush param or not batched then flush the buffer

                    buffer = batchBuffer;
                } else {
                    return;
                }

                if (!batched || flush) {
                    batchBuffer = null;
                } else {
                    // Create a new buffer

                    batchBuffer = ActiveMQBuffers.dynamicBuffer(BATCHING_BUFFER_SIZE);
                }
            }

            // depending on if we need to flush or not we can use a voidPromise or
            // use a normal promise
            final ByteBuf buf = buffer.byteBuf();
            final ChannelPromise promise;
            if (flush || futureListener != null) {
                promise = channel.newPromise();
            } else {
                promise = channel.voidPromise();
            }

            EventLoop eventLoop = channel.eventLoop();
            boolean inEventLoop = eventLoop.inEventLoop();
            if (!inEventLoop) {
                if (futureListener != null) {
                    channel.writeAndFlush(buf, promise).addListener(futureListener);
                } else {
                    channel.writeAndFlush(buf, promise);
                }
            } else {
                // create a task which will be picked up by the eventloop and trigger the write.
                // This is mainly needed as this method is triggered by different threads for the same channel.
                // if we not do this we may produce out of order writes.
                final Runnable task = new Runnable() {
                    @Override
                    public void run() {
                        if (futureListener != null) {
                            channel.writeAndFlush(buf, promise).addListener(futureListener);
                        } else {
                            channel.writeAndFlush(buf, promise);
                        }
                    }
                };
                // execute the task on the eventloop
                eventLoop.execute(task);
            }

            // only try to wait if not in the eventloop otherwise we will produce a deadlock
            if (flush && !inEventLoop) {
                while (true) {
                    try {
                        boolean ok = promise.await(10000);

                        if (!ok) {
                            ActiveMQClientLogger.LOGGER.timeoutFlushingPacket();
                        }

                        break;
                    } catch (InterruptedException e) {
                        throw new ActiveMQInterruptedException(e);
                    }
                }
            }
        } finally {
            writeLock.release();
        }
    } catch (InterruptedException e) {
        throw new ActiveMQInterruptedException(e);
    }
}

From source file:org.apache.hadoop.hbase.io.asyncfs.AsyncFSOutputHelper.java

License:Apache License

/**
 * Create {@link FanOutOneBlockAsyncDFSOutput} for {@link DistributedFileSystem}, and a simple
 * implementation for other {@link FileSystem} which wraps around a {@link FSDataOutputStream}.
 *//*  w  ww .  j ava  2  s . c  o m*/
public static AsyncFSOutput createOutput(FileSystem fs, Path f, boolean overwrite, boolean createParent,
        short replication, long blockSize, final EventLoop eventLoop) throws IOException {
    if (fs instanceof DistributedFileSystem) {
        return FanOutOneBlockAsyncDFSOutputHelper.createOutput((DistributedFileSystem) fs, f, overwrite,
                createParent, replication, blockSize, eventLoop);
    }
    final FSDataOutputStream fsOut;
    int bufferSize = fs.getConf().getInt(CommonConfigurationKeysPublic.IO_FILE_BUFFER_SIZE_KEY,
            CommonConfigurationKeysPublic.IO_FILE_BUFFER_SIZE_DEFAULT);
    if (createParent) {
        fsOut = fs.create(f, overwrite, bufferSize, replication, blockSize, null);
    } else {
        fsOut = fs.createNonRecursive(f, overwrite, bufferSize, replication, blockSize, null);
    }
    final ExecutorService flushExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder()
            .setDaemon(true).setNameFormat("AsyncFSOutputFlusher-" + f.toString().replace("%", "%%")).build());
    return new AsyncFSOutput() {

        private final ByteArrayOutputStream out = new ByteArrayOutputStream();

        @Override
        public void write(final byte[] b, final int off, final int len) {
            if (eventLoop.inEventLoop()) {
                out.write(b, off, len);
            } else {
                eventLoop.submit(new Runnable() {
                    public void run() {
                        out.write(b, off, len);
                    }
                }).syncUninterruptibly();
            }
        }

        @Override
        public void write(byte[] b) {
            write(b, 0, b.length);
        }

        @Override
        public void recoverAndClose(CancelableProgressable reporter) throws IOException {
            fsOut.close();
        }

        @Override
        public DatanodeInfo[] getPipeline() {
            return new DatanodeInfo[0];
        }

        @Override
        public <A> void flush(final A attachment, final CompletionHandler<Long, ? super A> handler,
                final boolean sync) {
            flushExecutor.execute(new Runnable() {

                @Override
                public void run() {
                    try {
                        synchronized (out) {
                            out.writeTo(fsOut);
                            out.reset();
                        }
                    } catch (final IOException e) {
                        eventLoop.execute(new Runnable() {

                            @Override
                            public void run() {
                                handler.failed(e, attachment);
                            }
                        });
                        return;
                    }
                    try {
                        if (sync) {
                            fsOut.hsync();
                        } else {
                            fsOut.hflush();
                        }
                        final long pos = fsOut.getPos();
                        eventLoop.execute(new Runnable() {

                            @Override
                            public void run() {
                                handler.completed(pos, attachment);
                            }
                        });
                    } catch (final IOException e) {
                        eventLoop.execute(new Runnable() {

                            @Override
                            public void run() {
                                handler.failed(e, attachment);
                            }
                        });
                    }
                }
            });
        }

        @Override
        public void close() throws IOException {
            try {
                flushExecutor.submit(new Callable<Void>() {

                    @Override
                    public Void call() throws Exception {
                        synchronized (out) {
                            out.writeTo(fsOut);
                            out.reset();
                        }
                        return null;
                    }
                }).get();
            } catch (InterruptedException e) {
                throw new InterruptedIOException();
            } catch (ExecutionException e) {
                Throwables.propagateIfPossible(e.getCause(), IOException.class);
                throw new IOException(e.getCause());
            } finally {
                flushExecutor.shutdown();
            }
            fsOut.close();
        }

        @Override
        public int buffered() {
            return out.size();
        }
    };
}

From source file:org.fusesource.hawtdispatch.netty.HawtSocketChannel.java

License:Apache License

@Override
public ChannelFuture shutdownOutput(final ChannelPromise promise) {
    EventLoop loop = eventLoop();
    if (loop.inEventLoop()) {
        boolean success = false;
        try {//  www .java 2 s. c  o  m
            javaChannel().socket().shutdownOutput();
            success = true;
            promise.setSuccess();
        } catch (Throwable t) {
            promise.setFailure(t);
        } finally {
            if (success) {
                outputShutdown = true;
            }
        }
    } else {
        loop.execute(new Runnable() {
            @Override
            public void run() {
                shutdownOutput(promise);
            }
        });
    }
    return promise;
}

From source file:org.hornetq.core.remoting.impl.netty.NettyConnection.java

License:Apache License

public void write(HornetQBuffer buffer, final boolean flush, final boolean batched) {

    try {/*w w w . ja v a 2  s . c  om*/
        writeLock.acquire();

        try {
            if (batchBuffer == null && batchingEnabled && batched && !flush) {
                // Lazily create batch buffer

                batchBuffer = HornetQBuffers.dynamicBuffer(BATCHING_BUFFER_SIZE);
            }

            if (batchBuffer != null) {
                batchBuffer.writeBytes(buffer, 0, buffer.writerIndex());

                if (batchBuffer.writerIndex() >= BATCHING_BUFFER_SIZE || !batched || flush) {
                    // If the batch buffer is full or it's flush param or not batched then flush the buffer

                    buffer = batchBuffer;
                } else {
                    return;
                }

                if (!batched || flush) {
                    batchBuffer = null;
                } else {
                    // Create a new buffer

                    batchBuffer = HornetQBuffers.dynamicBuffer(BATCHING_BUFFER_SIZE);
                }
            }

            // depending on if we need to flush or not we can use a voidPromise or
            // use a normal promise
            final ByteBuf buf = buffer.byteBuf();
            final ChannelPromise promise;
            if (flush) {
                promise = channel.newPromise();
            } else {
                promise = channel.voidPromise();
            }

            EventLoop eventLoop = channel.eventLoop();
            boolean inEventLoop = eventLoop.inEventLoop();
            if (!inEventLoop) {
                channel.writeAndFlush(buf, promise);
            } else {
                // create a task which will be picked up by the eventloop and trigger the write.
                // This is mainly needed as this method is triggered by different threads for the same channel.
                // if we not do this we may produce out of order writes.
                final Runnable task = new Runnable() {
                    @Override
                    public void run() {
                        channel.writeAndFlush(buf, promise);
                    }
                };
                // execute the task on the eventloop
                eventLoop.execute(task);
            }

            // only try to wait if not in the eventloop otherwise we will produce a deadlock
            if (flush && !inEventLoop) {
                while (true) {
                    try {
                        boolean ok = promise.await(10000);

                        if (!ok) {
                            HornetQClientLogger.LOGGER.timeoutFlushingPacket();
                        }

                        break;
                    } catch (InterruptedException e) {
                        throw new HornetQInterruptedException(e);
                    }
                }
            }
        } finally {
            writeLock.release();
        }
    } catch (InterruptedException e) {
        throw new HornetQInterruptedException(e);
    }
}

From source file:org.lanternpowered.server.network.NetworkSession.java

License:MIT License

/**
 * Sends a array of {@link Message}s and returns the {@link ChannelFuture}.
 *
 * @param messages The messages/*from   w  w w  .  ja  v  a  2s. co m*/
 * @return The channel future
 */
public ChannelFuture sendWithFuture(Message... messages) {
    checkNotNull(messages, "messages");
    checkArgument(messages.length != 0, "messages cannot be empty");
    final ChannelPromise promise = this.channel.newPromise();
    if (!this.channel.isActive()) {
        return promise;
    }
    promise.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
    // Don't bother checking if we are in the event loop,
    // there is only one message.
    if (messages.length == 1) {
        this.channel.writeAndFlush(messages[0], promise);
    } else {
        final EventLoop eventLoop = this.channel.eventLoop();
        final ChannelPromise voidPromise = this.channel.voidPromise();
        if (eventLoop.inEventLoop()) {
            final int last = messages.length - 1;
            for (int i = 0; i < last; i++) {
                ReferenceCountUtil.retain(messages[i]);
                this.channel.writeAndFlush(messages[i], voidPromise);
            }
            ReferenceCountUtil.retain(messages[last]);
            this.channel.writeAndFlush(messages[last], promise);
        } else {
            // If there are more then one message, combine them inside the
            // event loop to reduce overhead of wakeup calls and object creation

            // Create a copy of the list, to avoid concurrent modifications
            final List<Message> messages0 = ImmutableList.copyOf(messages);
            messages0.forEach(ReferenceCountUtil::retain);
            eventLoop.submit(() -> {
                final Iterator<Message> it0 = messages0.iterator();
                do {
                    final Message message0 = it0.next();
                    // Only use a normal channel promise for the last message
                    this.channel.writeAndFlush(message0, it0.hasNext() ? voidPromise : promise);
                } while (it0.hasNext());
            });
        }
    }
    return promise;
}

From source file:org.lanternpowered.server.network.NetworkSession.java

License:MIT License

/**
 * Sends a iterable of {@link Message}s.
 *
 * @param messages The messages//from   www  .  j  a  v a  2s. c  o  m
 */
public ChannelFuture sendWithFuture(Iterable<Message> messages) {
    checkNotNull(messages, "messages");
    final Iterator<Message> it = messages.iterator();
    checkArgument(it.hasNext(), "messages cannot be empty");
    final ChannelPromise promise = this.channel.newPromise();
    if (!this.channel.isActive()) {
        return promise;
    }
    promise.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
    Message message = it.next();
    // Don't bother checking if we are in the event loop,
    // there is only one message.
    if (!it.hasNext()) {
        this.channel.writeAndFlush(message, promise);
    } else {
        final EventLoop eventLoop = this.channel.eventLoop();
        final ChannelPromise voidPromise = this.channel.voidPromise();
        if (eventLoop.inEventLoop()) {
            while (true) {
                final boolean next = it.hasNext();
                // Only use a normal channel promise for the last message
                this.channel.writeAndFlush(message, next ? voidPromise : promise);
                if (!next) {
                    break;
                }
                message = it.next();
                ReferenceCountUtil.retain(message);
            }
        } else {
            // If there are more then one message, combine them inside the
            // event loop to reduce overhead of wakeup calls and object creation

            // Create a copy of the list, to avoid concurrent modifications
            final List<Message> messages0 = ImmutableList.copyOf(messages);
            messages0.forEach(ReferenceCountUtil::retain);
            eventLoop.submit(() -> {
                final Iterator<Message> it0 = messages0.iterator();
                do {
                    final Message message0 = it0.next();
                    // Only use a normal channel promise for the last message
                    this.channel.writeAndFlush(message0, it0.hasNext() ? voidPromise : promise);
                } while (it0.hasNext());
            });
        }
    }
    return promise;
}

From source file:org.lanternpowered.server.network.NetworkSession.java

License:MIT License

/**
 * Sends a array of {@link Message}s./*from   w w w.j a v  a2  s.  com*/
 *
 * @param messages The messages
 */
public void send(Message... messages) {
    checkNotNull(messages, "messages");
    checkArgument(messages.length != 0, "messages cannot be empty");
    if (!this.channel.isActive()) {
        return;
    }
    final ChannelPromise voidPromise = this.channel.voidPromise();
    if (messages.length == 1) {
        this.channel.writeAndFlush(messages[0], voidPromise);
    } else {
        final EventLoop eventLoop = this.channel.eventLoop();
        if (eventLoop.inEventLoop()) {
            for (Message message : messages) {
                ReferenceCountUtil.retain(message);
                this.channel.writeAndFlush(message, voidPromise);
            }
        } else {
            // If there are more then one message, combine them inside the
            // event loop to reduce overhead of wakeup calls and object creation

            // Create a copy of the list, to avoid concurrent modifications
            final List<Message> messages0 = ImmutableList.copyOf(messages);
            messages0.forEach(ReferenceCountUtil::retain);
            eventLoop.submit(() -> {
                for (Message message0 : messages0) {
                    this.channel.writeAndFlush(message0, voidPromise);
                }
            });
        }
    }
}

From source file:org.lanternpowered.server.network.NetworkSession.java

License:MIT License

/**
 * Sends a iterable of {@link Message}s.
 *
 * @param messages The messages//w ww .ja v  a  2 s  .co m
 */
public void send(Iterable<Message> messages) {
    checkNotNull(messages, "messages");
    final Iterator<Message> it = messages.iterator();
    checkArgument(it.hasNext(), "messages cannot be empty");
    Message message = it.next();
    // Don't bother checking if we are in the event loop,
    // there is only one message.
    final ChannelPromise voidPromise = this.channel.voidPromise();
    if (!it.hasNext()) {
        this.channel.writeAndFlush(message, voidPromise);
    } else {
        final EventLoop eventLoop = this.channel.eventLoop();
        if (eventLoop.inEventLoop()) {
            for (Message message0 : messages) {
                this.channel.writeAndFlush(message0, voidPromise);
            }
        } else {
            // If there are more then one message, combine them inside the
            // event loop to reduce overhead of wakeup calls and object creation

            // Create a copy of the list, to avoid concurrent modifications
            final List<Message> messages0 = ImmutableList.copyOf(messages);
            eventLoop.submit(() -> {
                for (Message message0 : messages0) {
                    this.channel.writeAndFlush(message0, voidPromise);
                }
            });
        }
    }
}