@Override
    public void next(Object value) {
      if (value == null) {
        fail(new NullPointerException("value is null"));
        return;
      }
      if (done) {
        Exceptions.onNextDropped(value);
        return;
      }
      if (caughtUp && actual != null) {
        try {
          actual.onNext(value);
        } finally {
          ch.read();
          ReferenceCountUtil.release(value);
        }

      } else {
        Queue<Object> q = queue;
        if (q == null) {
          q = QueueSupplier.unbounded().get();
          queue = q;
        }
        q.offer(value);
        if (drain()) {
          caughtUp = true;
        }
      }
    }
示例#2
0
 /** Resumes the underlying packet reader. */
 private void resume() {
   mChannel.config().setAutoRead(true);
   mChannel.read();
 }
    boolean drain() {
      if (wip++ != 0) {
        return false;
      }

      int missed = 1;

      for (; ; ) {
        final Queue<Object> q = queue;
        final Subscriber<? super Object> a = actual;

        if (a == null) {
          return false;
        }

        long r = requested;
        long e = 0L;

        while (e != r) {
          if (isCancelled()) {
            return false;
          }

          boolean d = done;
          Object v = q != null ? q.poll() : null;
          boolean empty = v == null;

          if (d && empty) {
            cancelResource();
            if (q != null) {
              q.clear();
            }
            Throwable ex = error;
            if (ex != null) {
              a.onError(ex);
            } else {
              a.onComplete();
            }
            return false;
          }

          if (empty) {
            ch.read();
            break;
          }

          try {
            a.onNext(v);
          } finally {
            ReferenceCountUtil.release(v);
            ch.read();
          }

          e++;
        }

        if (e == r) {
          if (isCancelled()) {
            return false;
          }

          if (done && (q == null || q.isEmpty())) {
            cancelResource();
            if (q != null) {
              q.clear();
            }
            Throwable ex = error;
            if (ex != null) {
              a.onError(ex);
            } else {
              a.onComplete();
            }
            return false;
          }
        }

        if (e != 0L) {
          if (r != Long.MAX_VALUE) {
            if ((requested -= e) > 0L) {
              ch.read();
            }
          }
        }

        missed = (wip = wip - missed);
        if (missed == 0) {
          if (r == Long.MAX_VALUE) {
            ch.config().setAutoRead(true);
            ch.read();
            return true;
          }
          return false;
        }
      }
    }