1 /***
2 *
3 * Copyright 2005 LogicBlaze, Inc. http://www.logicblaze.com
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 **/
18 package org.logicblaze.lingo.util.locks;
19
20 import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
21 import edu.emory.mathcs.backport.java.util.concurrent.locks.Lock;
22 import edu.emory.mathcs.backport.java.util.concurrent.locks.ReentrantLock;
23
24 import java.util.LinkedList;
25
26 /***
27 * A server side version of a {@link Condition} which is used by a
28 * {@link ConditionServer} to implement distributed conditions.
29 *
30 * @version $Revision$
31 */
32 public class ConditionController {
33
34 private String id;
35 private Lock lock;
36 private LinkedList listeners = new LinkedList();
37 private int signalCount;
38 private int signalAllCount;
39
40 public ConditionController(String id, Lock lock) {
41 this.id = id;
42 this.lock = lock;
43 }
44
45 /***
46 * Returns whether or not this condition is active so that it can be cleaned
47 * up in a pool.
48 *
49 * @return true if this condition is active otherwise false indicating it
50 * can be deleted.
51 */
52 public boolean isActive() {
53 if (signalCount == 0 && signalAllCount == 0) {
54 lock.lock();
55 try {
56 return !listeners.isEmpty();
57 }
58 finally {
59 lock.unlock();
60 }
61 }
62 return true;
63 }
64
65 public void await(ConditionListener listener, long timeoutMillis) {
66
67 lock.lock();
68 try {
69 if (!pendingSignals(listener)) {
70 listeners.add(listener);
71 }
72 }
73 finally {
74 lock.unlock();
75 }
76 }
77
78 public void signal() {
79 lock.lock();
80 try {
81 if (listeners.isEmpty()) {
82
83
84
85
86 signalCount++;
87 }
88 else {
89 ConditionListener listener = (ConditionListener) listeners.remove();
90 listener.onSignal(id);
91 }
92 }
93 finally {
94 lock.unlock();
95 }
96 }
97
98 public void signalAll() {
99 lock.lock();
100 try {
101 if (listeners.isEmpty()) {
102
103
104
105
106 signalAllCount++;
107 }
108 else {
109 while (!listeners.isEmpty()) {
110 ConditionListener listener = (ConditionListener) listeners.remove();
111 listener.onSignalAll(id);
112 }
113 }
114 }
115 finally {
116 lock.unlock();
117 }
118 }
119
120 /***
121 * Purges any inactive listeners from the Map
122 */
123 public void purge() {
124
125 }
126
127 /***
128 * Returns true if there were pending signals
129 */
130 protected boolean pendingSignals(ConditionListener listener) {
131 boolean answer = true;
132 if (signalAllCount > 0) {
133 signalAllCount--;
134 listener.onSignalAll(id);
135 }
136 else if (signalCount > 0) {
137 signalCount--;
138 listener.onSignal(id);
139 }
140 else {
141 answer = false;
142 }
143 return answer;
144 }
145 }