code: @Override
      public final void dispose() {
          if (disposed) {
              return;
          }
  
          IoFuture disposalFuture;
          synchronized (disposalLock) {
              disposalFuture = this.disposalFuture;
              if (!disposing) {
                  disposing = true;
                  try {
                      this.disposalFuture = disposalFuture = dispose0();
                  } catch (Exception e) {
                      IoSession ioSession = this.disposalFuture != null ? this.disposalFuture.getSession() : null;
                      ExceptionMonitor.getInstance().exceptionCaught(e, ioSession);
                  } finally {
                      if (disposalFuture == null) {
                          disposed = true;
                      }
                  }
              }
          }
  
          if (disposalFuture != null) {
              disposalFuture.awaitUninterruptibly();
          }
  
          if (createdExecutor) {
              ExecutorService e = (ExecutorService) executor;
              e.shutdown();
              while (!e.isTerminated()) {
                  try {
                      e.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);
                  } catch (InterruptedException e1) {
                      // Ignore; it should end shortly.
                  }
              }
          }
  
          disposed = true;
      }
docs: {@inheritDoc}