View Javadoc

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                  // oneway
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              // oneway
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     // Properties
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 }