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.Condition;
22 import edu.emory.mathcs.backport.java.util.concurrent.locks.Lock;
23
24 import java.util.Date;
25
26 /***
27 * Implements a client side proxy to a remote {@link Condition}
28 *
29 * @version $Revision$
30 */
31 public class ConditionClient implements Condition {
32
33 private ConditionServer server;
34 private ConditionListener listener;
35 private String id;
36 private Lock lock;
37 private Condition localCondition;
38 private transient Thread signalledThread;
39 private long timeout = 5000L;
40
41 public ConditionClient(ConditionServer server, ConditionListener listener, String id, Lock lock) {
42 this.server = server;
43 this.listener = listener;
44 this.id = id;
45 this.lock = lock;
46 }
47
48 public void await() throws InterruptedException {
49 lock.lock();
50 try {
51 while (true) {
52
53 server.await(id, listener, timeout);
54 if (signalledThread == Thread.currentThread()) {
55 signalledThread = null;
56 break;
57 }
58 localCondition.await();
59 }
60 }
61 finally {
62 lock.unlock();
63 }
64 }
65
66 public void awaitUninterruptibly() {
67 }
68
69 public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
70 long millis = unit.convert(timeout, TimeUnit.MILLISECONDS);
71 lock.lock();
72 try {
73
74 server.await(id, listener, millis);
75 if (signalledThread == Thread.currentThread()) {
76 signalledThread = null;
77 }
78 else {
79 localCondition.await();
80 }
81 }
82 finally {
83 lock.unlock();
84 }
85 return false;
86 }
87
88 public boolean awaitUntil(Date arg0) throws InterruptedException {
89 return false;
90 }
91
92 public void signal() {
93 server.signal(id);
94 }
95
96 public void signalAll() {
97 server.signalAll(id);
98 }
99
100 public void onSignal() {
101 lock.lock();
102 signalledThread = Thread.currentThread();
103 try {
104 localCondition.signal();
105 }
106 finally {
107 lock.unlock();
108 }
109
110 }
111
112 public void onSignalAll() {
113 lock.lock();
114 signalledThread = Thread.currentThread();
115 try {
116 localCondition.signalAll();
117 }
118 finally {
119 lock.unlock();
120 }
121 }
122
123
124
125
126 public long getTimeout() {
127 return timeout;
128 }
129
130 /***
131 * Sets the failover time where if a server side condition server goes down,
132 * signals are re-requested again.
133 */
134 public void setTimeout(long timeout) {
135 this.timeout = timeout;
136 }
137 }