void fastPath() { final Iterator<? extends T> a = iterator; final Subscriber<? super T> s = actual; for (; ; ) { if (cancelled) { return; } T t; try { t = a.next(); } catch (Exception ex) { s.onError(ex); return; } if (cancelled) { return; } if (t == null) { s.onError(new NullPointerException("The iterator returned a null value")); return; } s.onNext(t); if (cancelled) { return; } boolean b; try { b = a.hasNext(); } catch (Exception ex) { s.onError(ex); return; } if (cancelled) { return; } if (!b) { s.onComplete(); return; } } }
@Override public void onError(Throwable e) { boolean emit; synchronized (this) { if (emitting) { missedTerminal = e; emit = false; } else { emitting = true; emit = true; } } if (emit) { child.onError(e); } else { hasError = true; } }
@Override public void subscribe(Subscriber<? super String> observer) { observer.onSubscribe(EmptySubscription.INSTANCE); boolean errorThrown = false; for (String s : valuesToReturn) { if (s == null) { System.out.println("throwing exception"); observer.onError(new NullPointerException()); errorThrown = true; // purposefully not returning here so it will continue calling onNext // so that we also test that we handle bad sequences like this } else { observer.onNext(s); } } if (!errorThrown) { observer.onComplete(); } }
@Override public void onError(Throwable e) { Object[] active; synchronized (subscribers) { active = subscribers.toArray(); subscribers.clear(); } try { s.onError(e); unsubscribe(); } finally { for (Object o : active) { @SuppressWarnings("unchecked") MergeItemSubscriber a = (MergeItemSubscriber) o; a.release(); } } }
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); } } } }
void slowPath(long n) { final Iterator<? extends T> a = iterator; final Subscriber<? super T> s = actual; long e = 0L; for (; ; ) { while (e != n) { T t; try { t = a.next(); } catch (Throwable ex) { s.onError(ex); return; } if (cancelled) { return; } if (t == null) { s.onError(new NullPointerException("The iterator returned a null value")); return; } s.onNext(t); if (cancelled) { return; } boolean b; try { b = a.hasNext(); } catch (Throwable ex) { s.onError(ex); return; } if (cancelled) { return; } if (!b) { s.onComplete(); return; } e++; } n = requested; if (n == e) { n = REQUESTED.addAndGet(this, -e); if (n == 0L) { return; } e = 0L; } } }