package com.hammurapi.common.concurrent;


/**
 * This class increments counter when created and 
 * decrements when run() method exits. When counter reaches zero, this
 * class invokes notifyAll() on the counter. The class shall be used for 
 * parallel execution of tasks when it is required to wait until all tasks
 * complete.
 * @author Pavel Vlasov
 *
 */
public class CountedRunnable implements Runnable {
	
	/**
	 * Counter to use with CounterRunnable.
	 * @author Pavel Vlasov
	 */
	public static class Counter {
		private int counter;
		
		synchronized void inc() {
			++counter;
		}
		
		synchronized void dec() {
			if (--counter <= 0) {
				notifyAll();
			}
		}
		
		public synchronized void join() throws InterruptedException {
			while (counter>0) {
				wait();
			}
		}
	}
	
	private Counter counter;
	private Runnable master;

	public CountedRunnable(Counter counter, Runnable master) {
		this.counter = counter;
		counter.inc();
		this.master = master;
	}

	final public void run() {
		try {
			master.run();
		} finally {
			counter.dec();
		}
	}

}
