Clover coverage report - PLT Utilities Test Coverage (plt-20120304-r5436)
Coverage timestamp: Sat Mar 3 2012 22:01:56 CST
file stats: LOC: 320   Methods: 24
NCLOC: 120   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
StateMonitor.java 13.6% 10% 20.8% 12.7%
coverage coverage
 1    /*BEGIN_COPYRIGHT_BLOCK*
 2   
 3    PLT Utilities BSD License
 4   
 5    Copyright (c) 2007-2010 JavaPLT group at Rice University
 6    All rights reserved.
 7   
 8    Developed by: Java Programming Languages Team
 9    Rice University
 10    http://www.cs.rice.edu/~javaplt/
 11   
 12    Redistribution and use in source and binary forms, with or without modification, are permitted
 13    provided that the following conditions are met:
 14   
 15    - Redistributions of source code must retain the above copyright notice, this list of conditions
 16    and the following disclaimer.
 17    - Redistributions in binary form must reproduce the above copyright notice, this list of
 18    conditions and the following disclaimer in the documentation and/or other materials provided
 19    with the distribution.
 20    - Neither the name of the JavaPLT group, Rice University, nor the names of the library's
 21    contributors may be used to endorse or promote products derived from this software without
 22    specific prior written permission.
 23   
 24    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 25    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 26    FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND
 27    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 28    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 29    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 30    IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 31    OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 32   
 33    *END_COPYRIGHT_BLOCK*/
 34   
 35    package edu.rice.cs.plt.concurrent;
 36   
 37    import java.io.Serializable;
 38    import java.util.concurrent.TimeUnit;
 39    import java.util.concurrent.TimeoutException;
 40   
 41    import edu.rice.cs.plt.lambda.Box;
 42    import edu.rice.cs.plt.lambda.Predicate;
 43   
 44    /**
 45    * <p>Provides a convenient facility for blocking until a state change explicitly occurs.
 46    * Each time the wrapped state value changes, the blocked threads check to see if the new state meets
 47    * a provided criteria.</p>
 48    *
 49    * <p>Ideally, this class would extend {@link ConcurrentBox}. Unfortunately, the methods of
 50    * {@link java.util.concurrent.atomic.AtomicReference} are {@code final}, and so they can't be overridden here.
 51    * Also, since locking is necessary when performing thread notification, these implementations simply use
 52    * locking, rather than relying on built-in non-blocking atomic primitives.</p>
 53    */
 54    public class StateMonitor<T> implements Box<T>, Serializable {
 55   
 56    private volatile T _state;
 57   
 58  1 public StateMonitor(T state) { _state = state; }
 59   
 60    /**
 61    * Get the current state. (No guarantee is made about how long this value is valid &mdash; a concurrent state
 62    * change may occur immediately.)
 63    */
 64  2 public T value() { return _state; }
 65   
 66    /** Change the state to {@code newState}. */
 67  1 public synchronized void set(T newState) {
 68  1 _state = newState;
 69  1 this.notifyAll();
 70    }
 71   
 72    /**
 73    * Change the state to {@code newState}; return the previous state.
 74    * @see java.util.concurrent.atomic.AtomicReference#getAndSet
 75    */
 76  0 public synchronized T getAndSet(T newState) {
 77  0 T result = _state;
 78  0 _state = newState;
 79  0 this.notifyAll();
 80  0 return result;
 81    }
 82   
 83    /**
 84    * If the current state is {@code expect}, change it to {@code update}. In this case, {@code true} is
 85    * returned. Otherwise, give up and return {@code false}.
 86    * @see java.util.concurrent.atomic.AtomicReference#compareAndSet
 87    */
 88  0 public synchronized boolean compareAndSet(T expect, T update) {
 89  0 if (_state == expect) {
 90  0 _state = update;
 91  0 this.notifyAll();
 92  0 return true;
 93    }
 94  0 else { return false; }
 95    }
 96   
 97    /**
 98    * Ensures that the state equals {@code expected} before continuing. Blocks if necessary.
 99    * @return The state at the time this method returns (always equal to {@code expected}).
 100    */
 101  4 public synchronized T ensureState(T expected) throws InterruptedException {
 102  2 while (!inState(expected)) { this.wait(); }
 103  3 return _state;
 104    }
 105   
 106    /**
 107    * Ensures that the state equals {@code expected} before continuing. Blocks if necessary; fails if the
 108    * the timeout is reached.
 109    * @param timeout Maximum wait time, in milliseconds.
 110    * @return The state at the time this method returns (always equal to {@code expected}).
 111    */
 112  0 public T ensureState(T expected, long timeout) throws InterruptedException, TimeoutException {
 113  0 return ensureState(expected, timeout, TimeUnit.MILLISECONDS);
 114    }
 115   
 116    /**
 117    * Ensures that the state equals {@code expected} before continuing. Blocks if necessary; fails if the
 118    * the timeout is reached.
 119    * @param timeout Maximum wait time, in {@code unit} units.
 120    * @param unit Units for {@code timeout}.
 121    * @return The state at the time this method returns (always equal to {@code expected}).
 122    */
 123  0 public synchronized T ensureState(T expected, long timeout, TimeUnit unit)
 124    throws InterruptedException, TimeoutException {
 125  0 if (!inState(expected)) {
 126  0 long timeoutTime = ConcurrentUtil.futureTimeNanos(timeout, unit);
 127  0 do { ConcurrentUtil.waitUntilNanos(this, timeoutTime); } while (!inState(expected));
 128    }
 129  0 return _state;
 130    }
 131   
 132    /**
 133    * Tries to ensure that the state equals {@code expected} before continuing. Blocks if necessary. Stops waiting
 134    * if interrupted.
 135    * @return The state at the time this method returns (if not interrupted, this is equal to {@code expected}).
 136    */
 137  0 public synchronized T attemptEnsureState(T expected) {
 138  0 try { return ensureState(expected); }
 139  0 catch (InterruptedException e) { return _state; }
 140    }
 141   
 142    /**
 143    * Tries to ensure that the state equals {@code expected} before continuing. Blocks if necessary. If interrupted
 144    * or if the timeout is reached, stops waiting.
 145    * @param timeout Maximum wait time, in milliseconds.
 146    * @return The state at the time this method returns (barring an interrupt or timeout, this is equal
 147    * to {@code expected}).
 148    */
 149  0 public T attemptEnsureState(T expected, long timeout) {
 150  0 try { ensureState(expected, timeout, TimeUnit.MILLISECONDS); return _state; }
 151  0 catch (InterruptedException e) { return _state; }
 152  0 catch (TimeoutException e) { return _state; }
 153    }
 154   
 155    /**
 156    * Tries to ensure that the monitor has been signaled before continuing. Blocks if necessary. If interrupted
 157    * or if the timeout is reached, stops waiting.
 158    * @param timeout Maximum wait time, in {@code unit} units.
 159    * @param unit Units for {@code timeout}.
 160    * @return The state at the time this method returns (barring an interrupt or timeout, this is equal
 161    * to {@code expected}).
 162    */
 163  0 public T attemptEnsureState(T expected, long timeout, TimeUnit unit) {
 164  0 try { ensureState(expected, timeout, unit); return _state; }
 165  0 catch (InterruptedException e) { return _state; }
 166  0 catch (TimeoutException e) { return _state; }
 167    }
 168   
 169    /**
 170    * Ensures that the state does not equal {@code wrong} before continuing. Blocks if necessary.
 171    * @return The state at the time this method returns (never equal to {@code wrong}).
 172    */
 173  0 public synchronized T ensureNotState(T wrong) throws InterruptedException {
 174  0 while (inState(wrong)) { this.wait(); }
 175  0 return _state;
 176    }
 177   
 178    /**
 179    * Ensures that the state does not equal {@code wrong} before continuing. Blocks if necessary; fails if the
 180    * the timeout is reached.
 181    * @param timeout Maximum wait time, in milliseconds.
 182    * @return The state at the time this method returns (always equal to {@code expected}).
 183    */
 184  0 public T ensureNotState(T wrong, long timeout) throws InterruptedException, TimeoutException {
 185  0 return ensureNotState(wrong, timeout, TimeUnit.MILLISECONDS);
 186    }
 187   
 188    /**
 189    * Ensures that the state does not equal {@code wrong} before continuing. Blocks if necessary; fails if the
 190    * the timeout is reached.
 191    * @param timeout Maximum wait time, in {@code unit} units.
 192    * @param unit Units for {@code timeout}.
 193    * @return The state at the time this method returns (always equal to {@code expected}).
 194    */
 195  0 public synchronized T ensureNotState(T wrong, long timeout, TimeUnit unit)
 196    throws InterruptedException, TimeoutException {
 197  0 if (inState(wrong)) {
 198  0 long timeoutTime = ConcurrentUtil.futureTimeNanos(timeout, unit);
 199  0 do { ConcurrentUtil.waitUntilNanos(this, timeoutTime); } while (inState(wrong));
 200    }
 201  0 return _state;
 202    }
 203   
 204    /**
 205    * Tries to ensure that the state does not equal {@code wrong} before continuing. Blocks if necessary.
 206    * Stops waiting if interrupted.
 207    * @return The state at the time this method returns (if not interrupted, this is not equal to {@code wrong}).
 208    */
 209  0 public synchronized T attemptEnsureNotState(T wrong) {
 210  0 try { return ensureNotState(wrong); }
 211  0 catch (InterruptedException e) { return _state; }
 212    }
 213   
 214    /**
 215    * Tries to ensure that the state does not equal {@code wrong} before continuing. Blocks if necessary.
 216    * If the wait is interrupted or the timeout is reached, stops waiting.
 217    * @param timeout Maximum wait time, in milliseconds.
 218    * @return The state at the time this method returns (barring an interrupt or timeout, this is not equal
 219    * to {@code wrong}).
 220    */
 221  0 public T attemptEnsureNotState(T expected, long timeout) {
 222  0 try { ensureNotState(expected, timeout, TimeUnit.MILLISECONDS); return _state; }
 223  0 catch (InterruptedException e) { return _state; }
 224  0 catch (TimeoutException e) { return _state; }
 225    }
 226   
 227    /**
 228    * Tries to ensure that the state does not equal {@code wrong} before continuing. Blocks if necessary.
 229    * If the wait is interrupted or the timeout is reached, stops waiting.
 230    * @param timeout Maximum wait time, in {@code unit} units.
 231    * @param unit Units for {@code timeout}.
 232    * @return The state at the time this method returns (barring an interrupt or timeout, this is not equal
 233    * to {@code wrong}).
 234    */
 235  0 public T attemptEnsureNotState(T expected, long timeout, TimeUnit unit) {
 236  0 try { ensureNotState(expected, timeout, unit); return _state; }
 237  0 catch (InterruptedException e) { return _state; }
 238  0 catch (TimeoutException e) { return _state; }
 239    }
 240   
 241   
 242    /**
 243    * Ensures that {@code predicate} accepts the current state before continuing. Blocks if necessary.
 244    * @return The state at the time this method returns (always a state accepted by {@code predicate}).
 245    */
 246  0 public synchronized T ensurePredicate(Predicate<? super T> predicate) throws InterruptedException {
 247  0 while (!predicate.contains(_state)) { this.wait(); }
 248  0 return _state;
 249    }
 250   
 251    /**
 252    * Ensures that {@code predicate} accepts the current state before continuing. Blocks if necessary; fails if the
 253    * the timeout is reached.
 254    * @param timeout Maximum wait time, in milliseconds.
 255    * @return The state at the time this method returns (always a state accepted by {@code predicate}).
 256    */
 257  0 public T ensurePredicate(Predicate<? super T> predicate, long timeout)
 258    throws InterruptedException, TimeoutException {
 259  0 return ensurePredicate(predicate, timeout, TimeUnit.MILLISECONDS);
 260    }
 261   
 262    /**
 263    * Ensures that {@code predicate} accepts the current state before continuing. Blocks if necessary; fails if the
 264    * the timeout is reached.
 265    * @param timeout Maximum wait time, in {@code unit} units.
 266    * @param unit Units for {@code timeout}.
 267    * @return The state at the time this method returns (always a state accepted by {@code predicate}).
 268    */
 269  0 public synchronized T ensurePredicate(Predicate<? super T> predicate, long timeout, TimeUnit unit)
 270    throws InterruptedException, TimeoutException {
 271  0 if (!predicate.contains(_state)) {
 272  0 long timeoutTime = ConcurrentUtil.futureTimeNanos(timeout, unit);
 273  0 do { ConcurrentUtil.waitUntilNanos(this, timeoutTime); } while (!predicate.contains(_state));
 274    }
 275  0 return _state;
 276    }
 277   
 278    /**
 279    * Tries to ensure that {@code predicate} accepts the current state before continuing. Blocks if necessary.
 280    * Stops waiting if interrupted.
 281    * @return The state at the time this method returns (if not interrupted, this was accepted by {@code predicate}).
 282    */
 283  0 public synchronized T attemptEnsurePredicate(Predicate<? super T> predicate) {
 284  0 try { return ensurePredicate(predicate); }
 285  0 catch (InterruptedException e) { return _state; }
 286    }
 287   
 288    /**
 289    * Tries to ensure that {@code predicate} accepts the current state before continuing. Blocks if necessary.
 290    * If the wait is interrupted or the timeout is reached, stops waiting.
 291    * @param timeout Maximum wait time, in milliseconds.
 292    * @return The state at the time this method returns (barring an interrupt or timeout, this was accepted
 293    * by {@code predicate}).
 294    */
 295  0 public T attemptEnsurePredicate(Predicate<? super T> predicate, long timeout) {
 296  0 try { ensurePredicate(predicate, timeout, TimeUnit.MILLISECONDS); return _state; }
 297  0 catch (InterruptedException e) { return _state; }
 298  0 catch (TimeoutException e) { return _state; }
 299    }
 300   
 301    /**
 302    * Tries to ensure that {@code predicate} accepts the current state before continuing. Blocks if necessary.
 303    * If the wait is interrupted or the timeout is reached, stops waiting.
 304    * @param timeout Maximum wait time, in {@code unit} units.
 305    * @param unit Units for {@code timeout}.
 306    * @return The state at the time this method returns (barring an interrupt or timeout, this was accepted
 307    * by {@code predicate}).
 308    */
 309  0 public T attemptEnsurePredicate(Predicate<? super T> predicate, long timeout, TimeUnit unit) {
 310  0 try { ensurePredicate(predicate, timeout, unit); return _state; }
 311  0 catch (InterruptedException e) { return _state; }
 312  0 catch (TimeoutException e) { return _state; }
 313    }
 314   
 315    /** Test whether the current state matches {@code expected}. Helper method for performing null-aware comparison. */
 316  5 private boolean inState(T expected) {
 317  5 return (expected == null) ? (_state == null) : expected.equals(_state);
 318    }
 319   
 320    }