blob: 5453b7072b477d64bc6ed8ef42733dd3baa3771e [file] [log] [blame]
Brian O'Connorc6713a82015-02-24 11:55:48 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Brian O'Connorc6713a82015-02-24 11:55:48 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onlab.util;
17
18import java.util.concurrent.TimeUnit;
19import java.util.concurrent.locks.AbstractQueuedSynchronizer;
20
21/**
22 * Mutable boolean that allows threads to wait for a specified value.
23 */
24public class BlockingBoolean extends AbstractQueuedSynchronizer {
25
26 private static final int TRUE = 1;
27 private static final int FALSE = 0;
28
29 /**
30 * Creates a new blocking boolean with the specified value.
31 *
32 * @param value the starting value
33 */
34 public BlockingBoolean(boolean value) {
35 setState(value ? TRUE : FALSE);
36 }
37
38 /**
39 * Causes the current thread to wait until the boolean equals the specified
40 * value unless the thread is {@linkplain Thread#interrupt interrupted}.
41 *
42 * @param value specified value
Thomas Vachuska3e2b6512015-03-05 09:25:03 -080043 * @throws InterruptedException if interrupted while waiting
Brian O'Connorc6713a82015-02-24 11:55:48 -080044 */
45 public void await(boolean value) throws InterruptedException {
46 acquireSharedInterruptibly(value ? TRUE : FALSE);
47 }
48
49 /**
50 * Causes the current thread to wait until the boolean equals the specified
51 * value unless the thread is {@linkplain Thread#interrupt interrupted},
52 * or the specified waiting time elapses.
53 *
54 * @param value specified value
55 * @param timeout the maximum time to wait
56 * @param unit the time unit of the {@code timeout} argument
57 * @return {@code true} if the count reached zero and {@code false}
58 * if the waiting time elapsed before the count reached zero
Thomas Vachuska3e2b6512015-03-05 09:25:03 -080059 * @throws InterruptedException if interrupted while waiting
Brian O'Connorc6713a82015-02-24 11:55:48 -080060 */
61 public boolean await(boolean value, long timeout, TimeUnit unit)
62 throws InterruptedException {
63 return tryAcquireSharedNanos(value ? TRUE : FALSE, unit.toNanos(timeout));
64 }
65
66 protected int tryAcquireShared(int acquires) {
67 return (getState() == acquires) ? 1 : -1;
68 }
69
70 /**
71 * Sets the value of the blocking boolean.
72 *
73 * @param value new value
74 */
75 public void set(boolean value) {
76 releaseShared(value ? TRUE : FALSE);
77 }
78
79 /**
80 * Gets the value of the blocking boolean.
81 *
82 * @return current value
83 */
84 public boolean get() {
85 return getState() == TRUE;
86 }
87
88 protected boolean tryReleaseShared(int releases) {
89 // Signal on state change only
90 int state = getState();
91 if (state == releases) {
92 return false;
93 }
94 return compareAndSetState(state, releases);
95 }
96
97}