Ejemplo n.º 1
0
 public void setProducer(Producer p) {
   synchronized (this) {
     if (emitting) {
       missedProducer = p != null ? p : NULL_PRODUCER;
       return;
     }
     emitting = true;
   }
   boolean skipFinal = false;
   try {
     currentProducer = p;
     long r = requested;
     if (p != null && r != 0) {
       p.request(r);
     }
     emitLoop();
     skipFinal = true;
   } finally {
     if (!skipFinal) {
       synchronized (this) {
         emitting = false;
       }
     }
   }
 }
Ejemplo n.º 2
0
  @Override
  public void request(long n) {
    if (n < 0) {
      throw new IllegalArgumentException("n >= 0 required");
    }
    if (n == 0) {
      return;
    }
    synchronized (this) {
      if (emitting) {
        missedRequested += n;
        return;
      }
      emitting = true;
    }
    boolean skipFinal = false;
    try {
      long r = requested;
      long u = r + n;
      if (u < 0) {
        u = Long.MAX_VALUE;
      }
      requested = u;

      Producer p = currentProducer;
      if (p != null) {
        p.request(n);
      }

      emitLoop();
      skipFinal = true;
    } finally {
      if (!skipFinal) {
        synchronized (this) {
          emitting = false;
        }
      }
    }
  }
Ejemplo n.º 3
0
  void emitLoop() {
    final Subscriber<? super T> c = child;

    outer:
    for (; ; ) {
      long localRequested;
      Producer localProducer;
      Object localTerminal;
      List<T> q;
      synchronized (this) {
        localRequested = missedRequested;
        localProducer = missedProducer;
        localTerminal = missedTerminal;
        q = queue;
        if (localRequested == 0L && localProducer == null && q == null && localTerminal == null) {
          emitting = false;
          return;
        }
        missedRequested = 0L;
        missedProducer = null;
        queue = null;
        missedTerminal = null;
      }
      boolean empty = q == null || q.isEmpty();
      if (localTerminal != null) {
        if (localTerminal != Boolean.TRUE) {
          c.onError((Throwable) localTerminal);
          return;
        } else if (empty) {
          c.onCompleted();
          return;
        }
      }
      long e = 0;
      if (q != null) {
        for (T v : q) {
          if (c.isUnsubscribed()) {
            return;
          } else if (hasError) {
            continue outer; // if an error has been set, shortcut the loop and act on it
          }
          try {
            c.onNext(v);
          } catch (Throwable ex) {
            Exceptions.throwOrReport(ex, c, v);
            return;
          }
        }
        e += q.size();
      }
      long r = requested;
      // if requested is max, we don't do any accounting
      if (r != Long.MAX_VALUE) {
        // if there were missing requested, add it up
        if (localRequested != 0L) {
          long u = r + localRequested;
          if (u < 0) {
            u = Long.MAX_VALUE;
          }
          r = u;
        }
        // if there were emissions and we don't run on max since the last check, subtract
        if (e != 0L && r != Long.MAX_VALUE) {
          long u = r - e;
          if (u < 0) {
            throw new IllegalStateException("More produced than requested");
          }
          r = u;
        }
        requested = r;
      }
      if (localProducer != null) {
        if (localProducer == NULL_PRODUCER) {
          currentProducer = null;
        } else {
          currentProducer = localProducer;
          if (r != 0L) {
            localProducer.request(r);
          }
        }
      } else {
        Producer p = currentProducer;
        if (p != null && localRequested != 0L) {
          p.request(localRequested);
        }
      }
    }
  }