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.ScheduledExecutorService;
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 org.logicblaze.lingo.util.DefaultTimeoutMap;
25  import org.logicblaze.lingo.util.ScheduledTask;
26  import org.logicblaze.lingo.util.TimeoutMap;
27  import org.logicblaze.lingo.util.TimeoutMapEntry;
28  
29  /***
30   * A server side implementation of ConditionServer.
31   * 
32   * @version $Revision$
33   */
34  public class ConditionServerImpl implements ConditionServer {
35  
36      private TimeoutMap map = new DefaultTimeoutMap() {
37          protected boolean isValidForEviction(TimeoutMapEntry entry) {
38              ConditionController condition = (ConditionController) entry.getValue();
39              return !condition.isActive();
40          }
41      };
42      private ScheduledTask schedule;
43      private final long inactivityTimeout;
44  
45      public ConditionServerImpl(ScheduledExecutorService executor, long inactivityTimeout) {
46          this.inactivityTimeout = inactivityTimeout;
47          this.schedule = new ScheduledTask(map, executor, inactivityTimeout);
48      }
49  
50      public void await(String id, ConditionListener listener, long timeoutMillis) {
51          ConditionController condition = getCondition(id);
52          condition.await(listener, timeoutMillis);
53      }
54  
55      public void signal(String id) {
56          ConditionController condition = getCondition(id);
57          condition.signal();
58      }
59  
60      public void signalAll(String id) {
61          ConditionController condition = getCondition(id);
62          condition.signalAll();
63      }
64  
65      public void purge() {
66          Object[] keys = map.getKeys();
67          for (int i = 0; i < keys.length; i++) {
68              String id = (String) keys[i];
69              ConditionController condition = (ConditionController) map.get(id);
70              if (condition != null) {
71                  condition.purge();
72              }
73          }
74  
75          // now lets purge any dead controllers
76          map.purge();
77      }
78  
79      public void stop() {
80          schedule.stop();
81      }
82  
83      protected ConditionController getCondition(String id) {
84          synchronized (map) {
85              ConditionController answer = (ConditionController) map.get(id);
86              if (answer == null) {
87                  answer = createCondition(id);
88                  map.put(id, answer, inactivityTimeout);
89              }
90              return answer;
91          }
92      }
93  
94      protected ConditionController createCondition(String id) {
95          return new ConditionController(id, createLock(id));
96      }
97  
98      /***
99       * Factory method to change a lock
100      */
101     protected Lock createLock(String id) {
102         return new ReentrantLock();
103     }
104 }