blob: 1e820f94568973283a32ee10af434e0e95a94214 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
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 */
16
17package android.os;
18
19/**
20 * Class that implements the condition variable locking paradigm.
21 *
22 * <p>
23 * This differs from the built-in java.lang.Object wait() and notify()
24 * in that this class contains the condition to wait on itself. That means
25 * open(), close() and block() are sticky. If open() is called before block(),
26 * block() will not block, and instead return immediately.
27 *
28 * <p>
Pin Ting14a93102012-04-25 11:27:03 +080029 * This class uses itself as the object to wait on, so if you wait()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030 * or notify() on a ConditionVariable, the results are undefined.
31 */
32public class ConditionVariable
33{
34 private volatile boolean mCondition;
35
36 /**
37 * Create the ConditionVariable in the default closed state.
38 */
39 public ConditionVariable()
40 {
41 mCondition = false;
42 }
43
44 /**
45 * Create the ConditionVariable with the given state.
46 *
47 * <p>
48 * Pass true for opened and false for closed.
49 */
50 public ConditionVariable(boolean state)
51 {
52 mCondition = state;
53 }
54
55 /**
56 * Open the condition, and release all threads that are blocked.
57 *
58 * <p>
59 * Any threads that later approach block() will not block unless close()
60 * is called.
61 */
62 public void open()
63 {
64 synchronized (this) {
65 boolean old = mCondition;
66 mCondition = true;
67 if (!old) {
68 this.notifyAll();
69 }
70 }
71 }
72
73 /**
74 * Reset the condition to the closed state.
75 *
76 * <p>
77 * Any threads that call block() will block until someone calls open.
78 */
79 public void close()
80 {
81 synchronized (this) {
82 mCondition = false;
83 }
84 }
85
86 /**
87 * Block the current thread until the condition is opened.
88 *
89 * <p>
90 * If the condition is already opened, return immediately.
91 */
92 public void block()
93 {
94 synchronized (this) {
95 while (!mCondition) {
96 try {
97 this.wait();
98 }
99 catch (InterruptedException e) {
100 }
101 }
102 }
103 }
104
105 /**
106 * Block the current thread until the condition is opened or until
107 * timeout milliseconds have passed.
108 *
109 * <p>
110 * If the condition is already opened, return immediately.
111 *
Nicolas Prevot555f1982014-09-01 12:24:05 +0100112 * @param timeout the maximum time to wait in milliseconds.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113 *
114 * @return true if the condition was opened, false if the call returns
115 * because of the timeout.
116 */
117 public boolean block(long timeout)
118 {
119 // Object.wait(0) means wait forever, to mimic this, we just
120 // call the other block() method in that case. It simplifies
121 // this code for the common case.
122 if (timeout != 0) {
123 synchronized (this) {
124 long now = System.currentTimeMillis();
125 long end = now + timeout;
126 while (!mCondition && now < end) {
127 try {
128 this.wait(end-now);
129 }
130 catch (InterruptedException e) {
131 }
132 now = System.currentTimeMillis();
133 }
134 return mCondition;
135 }
136 } else {
137 this.block();
138 return true;
139 }
140 }
141}