@Override public void run() { int missed = 1; final AbstractMpscLinkedQueue<Runnable> q = queue; for (;;) { if (disposed) { q.clear(); return; } for (;;) { Runnable run = q.poll(); if (run == null) { break; } run.run(); if (disposed) { q.clear(); return; } } if (disposed) { q.clear(); return; } missed = wip.addAndGet(-missed); if (missed == 0) { break; } } }
public final boolean isEmpty() { return lvConsumerNode() == lvProducerNode(); }
public AbstractMpscLinkedQueue() { producerNode = new AtomicReference<LinkedQueueNode<T>>(); consumerNode = new AtomicReference<LinkedQueueNode<T>>(); LinkedQueueNode<T> node = new LinkedQueueNode<T>(); spConsumerNode(node); xchgProducerNode(node);// this ensures correct construction: StoreLoad }
@Nullable public final T poll() { LinkedQueueNode<T> currConsumerNode = lpConsumerNode(); // don't load twice, it's alright LinkedQueueNode<T> nextNode = currConsumerNode.lvNext(); if (nextNode != null) { // we have to null out the value because we are going to hang on to the node final T nextValue = nextNode.getAndNullValue(); spConsumerNode(nextNode); return nextValue; } else if (currConsumerNode != lvProducerNode()) { // spin, we are no longer wait free while ((nextNode = currConsumerNode.lvNext()) == null) { } // NOPMD // got the next node... // we have to null out the value because we are going to hang on to the node final T nextValue = nextNode.getAndNullValue(); spConsumerNode(nextNode); return nextValue; } return null; }
@NonNull @Override public Disposable schedule(@NonNull Runnable run) { if (disposed) { return REJECTED; } Runnable decoratedRun = RxJavaCommonPlugins.onSchedule(run); BooleanRunnable br = new BooleanRunnable(decoratedRun); queue.offer(br); if (wip.getAndIncrement() == 0) { try { executor.execute(this); } catch (RejectedExecutionException ex) { disposed = true; queue.clear(); RxJavaCommonPlugins.onError(ex); return REJECTED; } } return br; }
@Override public void run() { c.decrementAndGet(); while (c.get() != 0) { } while (--i > 0) { q.poll(); } } };
public final boolean offer(final T e) { if (null == e) { throw new NullPointerException("Null is not a valid element"); } final LinkedQueueNode<T> nextNode = new LinkedQueueNode<T>(e); final LinkedQueueNode<T> prevProducerNode = xchgProducerNode(nextNode); // Should a producer thread get interrupted here the chain WILL be broken until that thread is resumed // and completes the store in prev.next. prevProducerNode.soNext(nextNode); // StoreStore return true; }
@Override public void dispose() { if (!disposed) { disposed = true; tasks.dispose(); if (wip.getAndIncrement() == 0) { queue.clear(); } } }
@Nullable public final T poll() { LinkedQueueNode<T> currConsumerNode = lpConsumerNode(); // don't load twice, it's alright LinkedQueueNode<T> nextNode = currConsumerNode.lvNext(); if (nextNode != null) { // we have to null out the value because we are going to hang on to the node final T nextValue = nextNode.getAndNullValue(); spConsumerNode(nextNode); return nextValue; } else if (currConsumerNode != lvProducerNode()) { // spin, we are no longer wait free while ((nextNode = currConsumerNode.lvNext()) == null) { } // NOPMD // got the next node... // we have to null out the value because we are going to hang on to the node final T nextValue = nextNode.getAndNullValue(); spConsumerNode(nextNode); return nextValue; } return null; }
@NonNull @Override public Disposable schedule(@NonNull Runnable run) { if (disposed) { return REJECTED; } Runnable decoratedRun = RxJavaCommonPlugins.onSchedule(run); BooleanRunnable br = new BooleanRunnable(decoratedRun); queue.offer(br); if (wip.getAndIncrement() == 0) { try { executor.execute(this); } catch (RejectedExecutionException ex) { disposed = true; queue.clear(); RxJavaCommonPlugins.onError(ex); return REJECTED; } } return br; }
public AbstractMpscLinkedQueue() { producerNode = new AtomicReference<LinkedQueueNode<T>>(); consumerNode = new AtomicReference<LinkedQueueNode<T>>(); LinkedQueueNode<T> node = new LinkedQueueNode<T>(); spConsumerNode(node); xchgProducerNode(node);// this ensures correct construction: StoreLoad }
public final boolean isEmpty() { return lvConsumerNode() == lvProducerNode(); }
public final boolean offer(final T e) { if (null == e) { throw new NullPointerException("Null is not a valid element"); } final LinkedQueueNode<T> nextNode = new LinkedQueueNode<T>(e); final LinkedQueueNode<T> prevProducerNode = xchgProducerNode(nextNode); // Should a producer thread get interrupted here the chain WILL be broken until that thread is resumed // and completes the store in prev.next. prevProducerNode.soNext(nextNode); // StoreStore return true; }
@Override public void dispose() { if (!disposed) { disposed = true; tasks.dispose(); if (wip.getAndIncrement() == 0) { queue.clear(); } } }
@Nullable public final T poll() { LinkedQueueNode<T> currConsumerNode = lpConsumerNode(); // don't load twice, it's alright LinkedQueueNode<T> nextNode = currConsumerNode.lvNext(); if (nextNode != null) { // we have to null out the value because we are going to hang on to the node final T nextValue = nextNode.getAndNullValue(); spConsumerNode(nextNode); return nextValue; } else if (currConsumerNode != lvProducerNode()) { // spin, we are no longer wait free while ((nextNode = currConsumerNode.lvNext()) == null) { } // NOPMD // got the next node... // we have to null out the value because we are going to hang on to the node final T nextValue = nextNode.getAndNullValue(); spConsumerNode(nextNode); return nextValue; } return null; }
@NonNull @Override public Disposable schedule(@NonNull Runnable run) { if (disposed) { return REJECTED; } Runnable decoratedRun = RxJavaCommonPlugins.onSchedule(run); BooleanRunnable br = new BooleanRunnable(decoratedRun); queue.offer(br); if (wip.getAndIncrement() == 0) { try { executor.execute(this); } catch (RejectedExecutionException ex) { disposed = true; queue.clear(); RxJavaCommonPlugins.onError(ex); return REJECTED; } } return br; }