001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.activemq.thread;
018
019/**
020 * A Valve is a synchronization object used enable or disable the "flow" of
021 * concurrent processing.
022 *
023 * @deprecated
024 */
025@Deprecated
026public final class Valve {
027
028    private final Object mutex = new Object();
029    private boolean on;
030    private int turningOff;
031    private int usage;
032
033    public Valve(boolean on) {
034        this.on = on;
035    }
036
037    /**
038     * Turns the valve on. This method blocks until the valve is off.
039     *
040     * @throws InterruptedException if wait is interrupted
041     */
042    public void turnOn() throws InterruptedException {
043        synchronized (mutex) {
044            while (on) {
045                mutex.wait();
046            }
047            on = true;
048            mutex.notifyAll();
049        }
050    }
051
052    public boolean isOn() {
053        synchronized (mutex) {
054            return on;
055        }
056    }
057
058    /**
059     * Turns the valve off. This method blocks until the valve is on and the
060     * valve is not in use.
061     *
062     * @throws InterruptedException if wait is interrupted
063     */
064    public void turnOff() throws InterruptedException {
065        synchronized (mutex) {
066            if (turningOff < 0) {
067                throw new IllegalStateException("Unbalanced turningOff: " + turningOff);
068            }
069            try {
070                ++turningOff;
071                while (usage > 0 || !on) {
072                    mutex.wait();
073                }
074                on = false;
075                mutex.notifyAll();
076            } finally {
077                --turningOff;
078            }
079        }
080    }
081
082    /**
083     * Increments the use counter of the valve. This method blocks if the valve
084     * is off, or is being turned off.
085     *
086     * @throws InterruptedException  if wait is interrupted
087     */
088    public void increment() throws InterruptedException {
089        synchronized (mutex) {
090            if (turningOff < 0) {
091                throw new IllegalStateException("Unbalanced turningOff: " + turningOff);
092            }
093            if (usage < 0) {
094                throw new IllegalStateException("Unbalanced usage: " + usage);
095            }
096            // Do we have to wait for the value to be on?
097            while (turningOff > 0 || !on) {
098                mutex.wait();
099            }
100            usage++;
101        }
102    }
103
104    /**
105     * Decrements the use counter of the valve.
106     */
107    public void decrement() {
108        synchronized (mutex) {
109            usage--;
110            if (turningOff < 0) {
111                throw new IllegalStateException("Unbalanced turningOff: " + turningOff);
112            }
113            if (usage < 0) {
114                throw new IllegalStateException("Unbalanced usage: " + usage);
115            }
116            if (turningOff > 0 && usage < 1) {
117                mutex.notifyAll();
118            }
119        }
120    }
121
122}