All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.davidmoten.rx.internal.operators.QueueWithResourcesNonBlockingUnsubscribe Maven / Gradle / Ivy

package com.github.davidmoten.rx.internal.operators;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Wraps a Queue (like a file based queue) to provide concurrency guarantees
 * around calls to the close() method. Extends AtomicBoolean to save allocation.
 * The AtomicBoolean represents the closed status of the queue.
 * 
 * @param 
 *            type of item on queue
 */
final class QueueWithResourcesNonBlockingUnsubscribe extends AbstractQueueWithResources {

    private volatile boolean unsubscribing;

    // ensures queue.close() doesn't occur until outstanding peek(),offer(),
    // poll(), isEmpty() calls have finished. When currentCalls is zero a
    // close request can be actioned.
    private final AtomicInteger currentCalls = new AtomicInteger(0);

    private final AtomicBoolean unsubscribed;

    QueueWithResourcesNonBlockingUnsubscribe(QueueWithResources queue) {
        super(queue);
        this.unsubscribing = false;
        this.unsubscribed = new AtomicBoolean(false);
    }

    @Override
    public T poll() {
        try {
            if (unsubscribing) {
                return null;
            } else {
                try {
                    currentCalls.incrementAndGet();
                    return super.poll();
                } finally {
                    currentCalls.decrementAndGet();
                }
            }
        } finally {
            checkUnsubscribe();
        }
    }

    @Override
    public boolean offer(T t) {
        try {
            if (unsubscribing) {
                return true;
            } else {
                try {
                    currentCalls.incrementAndGet();
                    return super.offer(t);
                } finally {
                    currentCalls.decrementAndGet();
                }
            }
        } finally {
            checkUnsubscribe();
        }
    }

    @Override
    public boolean isEmpty() {
        try {
            if (unsubscribing) {
                return true;
            } else {
                try {
                    currentCalls.incrementAndGet();
                    return super.isEmpty();
                } finally {
                    currentCalls.decrementAndGet();
                }
            }
        } finally {
            checkUnsubscribe();
        }
   }

    @Override
    public void unsubscribe() {
        unsubscribing = true;
        checkUnsubscribe();
    }

    private void checkUnsubscribe() {
        if (unsubscribing && currentCalls.get() == 0 && unsubscribed.compareAndSet(false, true)) {
            super.unsubscribe();
        }
    }

    @Override
    public void freeResources() {
        super.freeResources();
    }

    @Override
    public boolean isUnsubscribed() {
        return unsubscribed.get();

    }

    @Override
    public long resourcesSize() {
        return super.resourcesSize();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy