package de.renew.util;

/**
 * Implementation of the semaphore access control pattern. Stores and manages an internal counter
 * specifying the number of concurrent resource units available for use by threads.
 *
 * @author Olaf Kummer
 */
public class Semaphor {
    private int _counter;

    /**
     * Construct a new semaphore object with a specific counter.
     * @param counter the number of concurrent ressources available. 
     */
    public Semaphor(int counter) {
        this._counter = counter;
    }

    /**
     * Construct a new semaphore object with a counter of size 0. Note that a semaphore of size 0 will never
     * have an available resource and wait all threads probing it indefinitely.
     */
    public Semaphor() {
        this(0);
    }

    /**
     * Probe the thread. If some resource unit is still available, decrement the counter by 1 and proceed. If all resource units
     * has been used by other threads, wait the calling thread until a resource unit becomes available.
     */
    public synchronized void P() {
        while (_counter == 0) {
            try {
                wait();
            } catch (InterruptedException ignored) {
            }
        }
        _counter--;
    }

    /**
     * Release access to one resource unit, incrementing the counter by 1 and notifying all waiting threads that a resource may be claimed.
     */
    public synchronized void V() {
        _counter++;
        notify();
    }
}