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

co.paralleluniverse.strands.channels.QueuePrimitiveChannel Maven / Gradle / Ivy

Go to download

The core library for Fibers on Java, compatible with Java 11-16. Forked from puniverse/quasar

There is a newer version: 10.0.6
Show newest version
/*
 * Quasar: lightweight threads and actors for the JVM.
 * Copyright (c) 2013-2014, Parallel Universe Software Co. All rights reserved.
 * 
 * This program and the accompanying materials are dual-licensed under
 * either the terms of the Eclipse Public License v1.0 as published by
 * the Eclipse Foundation
 *  
 *   or (per the licensee's choosing)
 *  
 * under the terms of the GNU Lesser General Public License version 3.0
 * as published by the Free Software Foundation.
 */
package co.paralleluniverse.strands.channels;

import co.paralleluniverse.fibers.SuspendExecution;
import co.paralleluniverse.strands.Strand;
import co.paralleluniverse.strands.Stranded;
import co.paralleluniverse.strands.channels.Channels.OverflowPolicy;
import co.paralleluniverse.strands.queues.BasicSingleConsumerQueue;
import java.util.concurrent.TimeUnit;

/**
 * Single consumer!
 *
 * @author pron
 */
public class QueuePrimitiveChannel extends QueueChannel implements Stranded {
    private Strand owner;

    public QueuePrimitiveChannel(BasicSingleConsumerQueue queue, OverflowPolicy policy) {
        super(queue, policy, true);
    }

    @Override
    public void setStrand(Strand strand) {
        if (owner != null && strand != owner)
            throw new IllegalStateException("Channel " + this + " is already owned by " + owner);
        this.owner = strand;
    }

    @Override
    public Strand getStrand() {
        return owner;
    }

    protected void maybeSetCurrentStrandAsOwner() {
        if (owner == null)
            setStrand(Strand.currentStrand());
        else {
            assert Strand.equals(owner, Strand.currentStrand()) : "This method has been called by a different strand (thread or fiber) from that owning this object";
        }
    }

    protected void checkClosed() throws EOFException {
        if (isClosed()) {
            if(getCloseException() != null)
                throw new ProducerException(getCloseException());
            throw EOFException.instance;
        }
    }

    public boolean hasMessage() {
        return queue().hasNext();
    }
    
    boolean awaitItem() throws SuspendExecution, InterruptedException, EOFException {
        maybeSetCurrentStrandAsOwner();
        Object n;
        Object token = sync.register();
        for (int i = 0; !queue().hasNext(); i++) {
            if (isSendClosed()) {
                setReceiveClosed();
                checkClosed();
            }
            sync.await(i);
        }
        sync.unregister(token);
        return true;
    }

    boolean awaitItem(long timeout, TimeUnit unit) throws SuspendExecution, InterruptedException, EOFException {
        if (unit == null)
            return awaitItem();
        if (timeout <= 0)
            return queue().hasNext();

        maybeSetCurrentStrandAsOwner();
        Object n;

        long left = unit.toNanos(timeout);
        final long deadline = System.nanoTime() + left;

        Object token = sync.register();
        try {
            for (int i = 0; !queue().hasNext(); i++) {
                if (isSendClosed()) {
                    setReceiveClosed();
                    checkClosed();
                }
                sync.await(i, left, TimeUnit.NANOSECONDS);

                left = deadline - System.nanoTime();
                if (left <= 0)
                    return false;
            }
        } finally {
            sync.unregister(token);
        }
        return true;
    }

    protected BasicSingleConsumerQueue queue() {
        return (BasicSingleConsumerQueue) queue;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy