Package hj.lang

Source Code of hj.lang.phaser

package hj.lang;

import hj.runtime.wsh.Activity;
import hj.runtime.wsh.FinishScope;
import hj.runtime.wsh.phaser.PhaserRegModeImpl;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
*
* @author bchase
*   
*/
public class phaser {
   
    private int yetToSignal;
    private HashMap<Activity, Integer> signalers;
    private HashMap<Activity, Integer> waiters;
    private phaserMode mode;
    private Condition phaseAdvance;
    private ReentrantLock lock;
    private FinishScope scope;
   
    private Activity singleActivity;
    private Condition singleHolder;
   
    public phaser() {
        mode= phaserMode.SIG_WAIT_SINGLE;
        setUp();
    }
   
    public phaser(phaserMode mode) {
        this.mode = mode;
        setUp();
    }
   
    private void setUp() {
        yetToSignal = 0;
        signalers = new HashMap<Activity, Integer>();
        waiters = new HashMap<Activity, Integer>();
        lock = new ReentrantLock();
        phaseAdvance = lock.newCondition();
       
        singleActivity=null;
        singleHolder = lock.newCondition();
       
        /* Add the parent of the phaser to the finish scope it belongs to
         * The phaser has the parent in it to prevent it from advancing to the next phase
         * before the finish scope hits end scope
         * When the parent hits stopFinish(), the parent will deregister itself so that
         * the phaser can now advance to the next phase
         */
        Activity parent = (Activity) Thread.currentThread();
        scope = parent.getCurrentFinishScope();
        parent.addPhaser(new PhaserRegModeImpl(this,phaserMode.SIG_WAIT));
        scope.addPhaser(this);
        registerSignaler(parent);
        registerWaiter(parent);
    }
   
    public final void registerSignaler(Activity newParty) {
        try {
            lock.lock();
            if (newParty == null) return;
            if (signalers.containsKey(newParty) == false) {
                signalers.put(newParty, new Integer(0));
                yetToSignal++;
            }
        } finally {
            lock.unlock();
        }  
    }
   
    public final void registerWaiter(Activity newParty) {
        try {
            lock.lock();
            if (newParty == null) return;
            if (waiters.containsKey(newParty) == false) {
                waiters.put(newParty, new Integer(0));
            }
        } finally {
            lock.unlock();
        }
    }
   
    public void unregisterSignaler(Activity existingParty) {
        try {
            lock.lock();
            if (existingParty == null) return;
            if (signalers.containsKey(existingParty)) {
                int value = signalers.get(existingParty);
                if (value == 0) yetToSignal--;
                signalers.remove(existingParty);
                if (checkAdvancePhase()) {
                    advancePhase();
                }
            }
        } finally {
            lock.unlock();
        }
    }
   
    public void unregisterWaiter(Activity existingParty) {
        try {
            lock.lock();
            if (existingParty == null) return;
            if (waiters.containsKey(existingParty)) {
                waiters.remove(existingParty);
            }
        } finally {
            lock.unlock();
        }
    }
   
    //Advance phase --
    //  This methods should:
    //      -Decrement the signal value of all signalers
    //          -For each signaler that has a new signal value of
    //           zero, yetToSignal is incremented by one.
    //      -Increment all the wait values
    //      -Notify all blocked waiters that phase has advanced
    private void advancePhase() {
        try {
            lock.lock();
            for (Map.Entry<Activity, Integer> entry : signalers.entrySet()) {
                Activity signaler = entry.getKey();
                int signalValue = entry.getValue();
                signalers.put(signaler, signalValue-1);
                signalValue--;
                if (signalValue == 0) yetToSignal++;
            }
            for (Map.Entry<Activity, Integer> entry : waiters.entrySet()) {
                Activity waiter = entry.getKey();
                int waitValue = entry.getValue();
                waiters.put(waiter, waitValue+1);
            }
            phaseAdvance.signalAll();
        } finally {
            lock.unlock();
        }
    }
   
    public void phSignal(Activity signaler) {
        try {
            lock.lock();
            if (signalers.containsKey(signaler)) {
                int value = signalers.get(signaler);
                signalers.put(signaler, value+1);
                if (value == 0) yetToSignal--;
                if (checkAdvancePhase()) {
                    advancePhase();
                }
            }
        } finally {
            lock.unlock();
        }
    }
   
    public void phWait(Activity waiter) {
        try {
            lock.lock();
            if (waiter == null) return;
            //if (waiters.containsKey(waiter)) {
                while (waiters.get(waiter) <= 0) {
                    phaseAdvance.await();            
                }
                int waitValue = waiters.get(waiter);
                waiters.put(waiter, waitValue-1);
            //}
        } catch (InterruptedException ex) {
            Logger.getLogger(phaser.class.getName()).log(Level.SEVERE, null, ex);       
        } finally {
            lock.unlock();
        }
    }
   
    // Check to see if the phaser needs to advance or not
    private boolean checkAdvancePhase() {
        if (yetToSignal != 0)
            return false;
        if (singleActivity==null)
            return true;
        // If there is an activity assigned as the single, release it
        // The activity will advance the phase after the single statement
        singleHolder.signal();
        return false;
    }
   
    public boolean phSignalSingle(Activity single) {
        try {
            lock.lock();
            boolean isFirstSingle=false;
            if (singleActivity==null) {
                singleActivity=single;
                isFirstSingle=true;
            }
            phSignal(single);
            return isFirstSingle;
        } finally {
            lock.unlock();
        }
    }
   
    public void holdSingle(Activity single) {
        try {
            lock.lock();
            while (single == singleActivity && yetToSignal>0) {
                singleHolder.await();
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(phaser.class.getName()).log(Level.SEVERE, null, ex);       
        } finally {
            lock.unlock();
        }
    }
   
    public void phWaitSingle(Activity single) {
        try {
            lock.lock();
            if (single == singleActivity) {
                singleActivity=null;
                if (checkAdvancePhase()) {
                    advancePhase();
                }
            }
            phWait(single);
        } finally {
            lock.unlock();
        }
    }
   
    public phaserMode getMode() {
        return mode;
    }
}
TOP

Related Classes of hj.lang.phaser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.