Class ManualIoEventLoop

java.lang.Object
java.util.concurrent.AbstractExecutorService
All Implemented Interfaces:
EventLoop, EventLoopGroup, IoEventLoop, IoEventLoopGroup, EventExecutor, EventExecutorGroup, OrderedEventExecutor, ThreadAwareExecutor, java.lang.Iterable<EventExecutor>, java.util.concurrent.Executor, java.util.concurrent.ExecutorService, java.util.concurrent.ScheduledExecutorService

public class ManualIoEventLoop extends AbstractScheduledEventExecutor implements IoEventLoop
IoEventLoop implementation that is owned by the user and so needs to be driven by the user manually with the given Thread. This means that the user is responsible to call either runNow() or run(long) to execute IO and tasks that were submitted to this IoEventLoop.

This is for advanced use-cases only, where the user wants to own the Thread that drives the IoEventLoop to also do other work. Care must be taken that the or #waitAndRun() methods are called in a timely fashion.

  • Field Details

    • WAKEUP_TASK

      private static final java.lang.Runnable WAKEUP_TASK
    • ST_STARTED

      private static final int ST_STARTED
      See Also:
    • ST_SHUTTING_DOWN

      private static final int ST_SHUTTING_DOWN
      See Also:
    • ST_SHUTDOWN

      private static final int ST_SHUTDOWN
      See Also:
    • ST_TERMINATED

      private static final int ST_TERMINATED
      See Also:
    • state

      private final java.util.concurrent.atomic.AtomicInteger state
    • terminationFuture

      private final Promise<?> terminationFuture
    • taskQueue

      private final java.util.Queue<java.lang.Runnable> taskQueue
    • nonBlockingContext

      private final IoHandlerContext nonBlockingContext
    • blockingContext

      private final ManualIoEventLoop.BlockingIoHandlerContext blockingContext
    • parent

      private final IoEventLoopGroup parent
    • owningThread

      private final java.util.concurrent.atomic.AtomicReference<java.lang.Thread> owningThread
    • handler

      private final IoHandler handler
    • ticker

      private final Ticker ticker
    • gracefulShutdownQuietPeriod

      private volatile long gracefulShutdownQuietPeriod
    • gracefulShutdownTimeout

      private volatile long gracefulShutdownTimeout
    • gracefulShutdownStartTime

      private long gracefulShutdownStartTime
    • lastExecutionTime

      private long lastExecutionTime
    • initialized

      private boolean initialized
  • Constructor Details

  • Method Details

    • canBlock

      protected boolean canBlock()
      This allows to specify additional blocking conditions which will be used by the IoHandler to decide whether it is allowed to block or not.
    • ticker

      public final Ticker ticker()
      Description copied from interface: EventExecutorGroup
      The ticker for this executor. Usually the EventExecutorGroup.schedule(Runnable, long, TimeUnit) methods will follow the system ticker (i.e. System.nanoTime()), but especially for testing it is sometimes useful to have more control over the ticker. In that case, this method will be overridden. Code that schedules tasks on this executor should use this ticker in order to stay consistent with the executor (e.g. not be surprised by scheduled tasks running "early").
      Specified by:
      ticker in interface EventExecutorGroup
      Overrides:
      ticker in class AbstractScheduledEventExecutor
      Returns:
      The ticker for this scheduler
    • runNonBlockingTasks

      public final int runNonBlockingTasks(long timeoutNanos)
      Poll and run tasks from the task queue, until the task queue is empty or the given deadline is exceeded.
      If timeoutNanos is less or equals 0, no deadline is applied.
      Parameters:
      timeoutNanos - the maximum time in nanoseconds to run tasks.
    • runAllTasks

      private int runAllTasks(long timeoutNanos, boolean setCurrentExecutor)
    • run

      private int run(IoHandlerContext context, long runAllTasksTimeoutNanos)
    • runAllTasksBeforeDestroy

      private int runAllTasksBeforeDestroy()
    • runNow

      public final int runNow(long runAllTasksTimeoutNanos)
      Executes all ready IO and tasks for this IoEventLoop. This methods will NOT block and wait for IO / tasks to be ready, it will just return directly if there is nothing to do.

      Must be called from the owning Thread that was passed as a parameter on construction.

      Parameters:
      runAllTasksTimeoutNanos - the maximum time in nanoseconds to run tasks. If = 0, no timeout is applied; if < 0 it just perform I/O tasks.
      Returns:
      the number of IO and tasks executed.
      Throws:
      java.lang.IllegalStateException - if the method is not called from the owning Thread.
    • runNow

      public final int runNow()
      Run all ready IO and tasks for this IoEventLoop. This methods will NOT block and wait for IO / tasks to be ready, it will just return directly if there is nothing to do.

      Must be called from the owning Thread that was passed as a parameter on construction.

      Returns:
      the number of IO and tasks executed.
    • run

      public final int run(long waitNanos, long runAllTasksTimeoutNanos)
      Run all ready IO and tasks for this IoEventLoop. This methods will block and wait for IO / tasks to be ready if there is nothing to process atm for the given waitNanos.

      Must be called from the owning Thread that was passed as an parameter on construction.

      Parameters:
      waitNanos - the maximum amount of nanoseconds to wait before returning. IF 0 it will block until there is some IO / tasks ready, if -1 will not block at all and just return directly if there is nothing to run (like runNow()).
      runAllTasksTimeoutNanos - the maximum time in nanoseconds to run tasks. If = 0, no timeout is applied; if < 0 it just perform I/O tasks.
      Returns:
      the number of IO and tasks executed.
    • run

      public final int run(long waitNanos)
      Run all ready IO and tasks for this IoEventLoop. This methods will block and wait for IO / tasks to be ready if there is nothing to process atm for the given waitNanos.

      Must be called from the owning Thread that was passed as an parameter on construction.

      Parameters:
      waitNanos - the maximum amount of nanoseconds to wait before returning. IF 0 it will block until there is some IO / tasks ready, if -1 will not block at all and just return directly if there is nothing to run (like runNow()).
      Returns:
      the number of IO and tasks executed.
    • checkCurrentThread

      private void checkCurrentThread()
    • wakeup

      public final void wakeup()
      Force a wakeup and so the run(long) method will unblock and return even if there was nothing to do.
    • next

      public final ManualIoEventLoop next()
      Description copied from interface: EventExecutorGroup
      Returns one of the EventExecutors managed by this EventExecutorGroup.
      Specified by:
      next in interface EventExecutorGroup
      Specified by:
      next in interface EventLoopGroup
      Specified by:
      next in interface IoEventLoop
      Specified by:
      next in interface IoEventLoopGroup
      Overrides:
      next in class AbstractEventExecutor
    • parent

      public final IoEventLoopGroup parent()
      Description copied from interface: EventExecutor
      Return the EventExecutorGroup which is the parent of this EventExecutor,
      Specified by:
      parent in interface EventExecutor
      Specified by:
      parent in interface EventLoop
      Overrides:
      parent in class AbstractEventExecutor
    • register

      @Deprecated public final ChannelFuture register(Channel channel)
      Deprecated.
      Description copied from interface: EventLoopGroup
      Register a Channel with this EventLoop. The returned ChannelFuture will get notified once the registration was complete.
      Specified by:
      register in interface EventLoopGroup
      Specified by:
      register in interface IoEventLoopGroup
    • register

      @Deprecated public final ChannelFuture register(ChannelPromise promise)
      Deprecated.
      Description copied from interface: EventLoopGroup
      Register a Channel with this EventLoop using a ChannelFuture. The passed ChannelFuture will get notified once the registration was complete and also will get returned.
      Specified by:
      register in interface EventLoopGroup
      Specified by:
      register in interface IoEventLoopGroup
    • register

      public final Future<IoRegistration> register(IoHandle handle)
      Description copied from interface: IoEventLoop
      Register the IoHandle to the EventLoop for I/O processing.
      Specified by:
      register in interface IoEventLoop
      Specified by:
      register in interface IoEventLoopGroup
      Parameters:
      handle - the IoHandle to register.
      Returns:
      the Future that is notified once the operations completes.
    • registerForIo0

      private void registerForIo0(IoHandle handle, Promise<IoRegistration> promise)
    • register

      @Deprecated public final ChannelFuture register(Channel channel, ChannelPromise promise)
      Deprecated.
      Description copied from interface: EventLoopGroup
      Register a Channel with this EventLoop. The passed ChannelFuture will get notified once the registration was complete and also will get returned.
      Specified by:
      register in interface EventLoopGroup
    • isCompatible

      public final boolean isCompatible(java.lang.Class<? extends IoHandle> handleType)
      Description copied from interface: IoEventLoopGroup
      Returns true if the given type is compatible with this IoEventLoopGroup and so can be registered to the contained IoEventLoops, false otherwise.
      Specified by:
      isCompatible in interface IoEventLoop
      Specified by:
      isCompatible in interface IoEventLoopGroup
      Parameters:
      handleType - the type of the IoHandle.
      Returns:
      if compatible of not.
    • isIoType

      public final boolean isIoType(java.lang.Class<? extends IoHandler> handlerType)
      Description copied from interface: IoEventLoopGroup
      Returns true if the given IoHandler type is used by this IoEventLoopGroup, false otherwise.
      Specified by:
      isIoType in interface IoEventLoop
      Specified by:
      isIoType in interface IoEventLoopGroup
      Parameters:
      handlerType - the type of the IoHandler.
      Returns:
      if used or not.
    • inEventLoop

      public final boolean inEventLoop(java.lang.Thread thread)
      Description copied from interface: EventExecutor
      Return true if the given Thread is executed in the event loop, false otherwise.
      Specified by:
      inEventLoop in interface EventExecutor
    • setOwningThread

      public final void setOwningThread(java.lang.Thread owningThread)
      Set the owning thread that will call run(IoHandlerContext, long). May only be called once, and only if the owning thread was not set in the constructor already.
      Parameters:
      owningThread - The owning thread
    • shutdown0

      private void shutdown0(long quietPeriod, long timeout, int shutdownState)
    • shutdownGracefully

      public final Future<?> shutdownGracefully(long quietPeriod, long timeout, java.util.concurrent.TimeUnit unit)
      Description copied from interface: EventExecutorGroup
      Signals this executor that the caller wants the executor to be shut down. Once this method is called, EventExecutorGroup.isShuttingDown() starts to return true, and the executor prepares to shut itself down. Unlike EventExecutorGroup.shutdown(), graceful shutdown ensures that no tasks are submitted for 'the quiet period' (usually a couple seconds) before it shuts itself down. If a task is submitted during the quiet period, it is guaranteed to be accepted and the quiet period will start over.
      Specified by:
      shutdownGracefully in interface EventExecutorGroup
      Parameters:
      quietPeriod - the quiet period as described in the documentation
      timeout - the maximum amount of time to wait until the executor is EventExecutorGroup.shutdown() regardless if a task was submitted during the quiet period
      unit - the unit of quietPeriod and timeout
      Returns:
      the EventExecutorGroup.terminationFuture()
    • shutdown

      @Deprecated public final void shutdown()
      Deprecated.
      Specified by:
      shutdown in interface EventExecutorGroup
      Specified by:
      shutdown in interface java.util.concurrent.ExecutorService
      Specified by:
      shutdown in class AbstractEventExecutor
    • terminationFuture

      public final Future<?> terminationFuture()
      Description copied from interface: EventExecutorGroup
      Returns the Future which is notified when all EventExecutors managed by this EventExecutorGroup have been terminated.
      Specified by:
      terminationFuture in interface EventExecutorGroup
    • isShuttingDown

      public final boolean isShuttingDown()
      Description copied from interface: EventExecutorGroup
      Returns true if and only if all EventExecutors managed by this EventExecutorGroup are being shut down gracefully or was shut down.
      Specified by:
      isShuttingDown in interface EventExecutorGroup
    • isShutdown

      public final boolean isShutdown()
      Specified by:
      isShutdown in interface java.util.concurrent.ExecutorService
    • isTerminated

      public final boolean isTerminated()
      Specified by:
      isTerminated in interface java.util.concurrent.ExecutorService
    • awaitTermination

      public final boolean awaitTermination(long timeout, java.util.concurrent.TimeUnit unit) throws java.lang.InterruptedException
      Specified by:
      awaitTermination in interface java.util.concurrent.ExecutorService
      Throws:
      java.lang.InterruptedException
    • execute

      public final void execute(java.lang.Runnable command)
      Specified by:
      execute in interface java.util.concurrent.Executor
    • hasTasks

      private boolean hasTasks()
    • confirmShutdown

      private boolean confirmShutdown()
    • invokeAny

      public final <T> T invokeAny(java.util.Collection<? extends java.util.concurrent.Callable<T>> tasks) throws java.lang.InterruptedException, java.util.concurrent.ExecutionException
      Specified by:
      invokeAny in interface java.util.concurrent.ExecutorService
      Overrides:
      invokeAny in class java.util.concurrent.AbstractExecutorService
      Throws:
      java.lang.InterruptedException
      java.util.concurrent.ExecutionException
    • invokeAny

      public final <T> T invokeAny(java.util.Collection<? extends java.util.concurrent.Callable<T>> tasks, long timeout, java.util.concurrent.TimeUnit unit) throws java.lang.InterruptedException, java.util.concurrent.ExecutionException, java.util.concurrent.TimeoutException
      Specified by:
      invokeAny in interface java.util.concurrent.ExecutorService
      Overrides:
      invokeAny in class java.util.concurrent.AbstractExecutorService
      Throws:
      java.lang.InterruptedException
      java.util.concurrent.ExecutionException
      java.util.concurrent.TimeoutException
    • invokeAll

      public final <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>> tasks) throws java.lang.InterruptedException
      Specified by:
      invokeAll in interface java.util.concurrent.ExecutorService
      Overrides:
      invokeAll in class java.util.concurrent.AbstractExecutorService
      Throws:
      java.lang.InterruptedException
    • invokeAll

      public final <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>> tasks, long timeout, java.util.concurrent.TimeUnit unit) throws java.lang.InterruptedException
      Specified by:
      invokeAll in interface java.util.concurrent.ExecutorService
      Overrides:
      invokeAll in class java.util.concurrent.AbstractExecutorService
      Throws:
      java.lang.InterruptedException
    • throwIfInEventLoop

      private void throwIfInEventLoop(java.lang.String method)