KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > objectserver > lockmanager > impl > LockTimer


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.objectserver.lockmanager.impl;
5
6 import com.tc.logging.TCLogger;
7 import com.tc.logging.TCLogging;
8 import com.tc.net.protocol.tcm.MessageChannel;
9 import com.tc.object.net.DSOChannelManager;
10 import com.tc.object.net.NoSuchChannelException;
11 import com.tc.objectserver.lockmanager.api.LockAwardContext;
12 import com.tc.objectserver.lockmanager.api.LockEventListener;
13 import com.tc.util.Assert;
14
15 import java.util.HashMap JavaDoc;
16 import java.util.HashSet JavaDoc;
17 import java.util.Map JavaDoc;
18 import java.util.Set JavaDoc;
19 import java.util.Timer JavaDoc;
20 import java.util.TimerTask JavaDoc;
21
22 /**
23  * Implementation of a lock timer.
24  */

25 public class LockTimer implements LockEventListener {
26
27   private static final TCLogger logger = TCLogging.getLogger(LockTimer.class);
28
29   private final Timer JavaDoc timer = new Timer JavaDoc(true);
30   private final DSOChannelManager channelManager;
31   private final Map JavaDoc tasks = new HashMap JavaDoc();
32   private final Set JavaDoc uncontended = new HashSet JavaDoc();
33
34   LockTimer(DSOChannelManager channelManager) {
35     this.channelManager = channelManager;
36   }
37
38   synchronized void startTimerForLock(LockAwardContext awardContext) {
39     logStartTimerForLock(awardContext);
40     LockTimeoutTask task = new LockTimeoutTask(awardContext);
41     putTimerTask(task);
42     timer.schedule(task, task.getTimeout());
43   }
44
45   synchronized LockAwardContext cancel(LockAwardContext awardContext) {
46     logCancel(awardContext);
47     LockTimeoutTask task = removeTimerTask(awardContext);
48     if (task != null) {
49       task.cancel();
50       return task.awardContext;
51     } else {
52       return null;
53     }
54   }
55
56   /*********************************************************************************************************************
57    * LockEventListener interface
58    */

59
60   /**
61    * If the waiter count is 1, then this is the first waiter. We should schedule a timeout for this lock award context.
62    * Otherwise, we shouldn't do anything.
63    */

64   public synchronized void notifyAddPending(int waiterCount, LockAwardContext ctxt) {
65     Assert.eval(waiterCount > 0);
66     if (waiterCount == 1) {
67       logNotifyAddWaitingStartTimer(waiterCount, ctxt);
68       startTimerForLock(ctxt);
69     } else {
70       logNotifyAddWaitingUncontended(waiterCount, ctxt);
71       uncontended.add(ctxt);
72     }
73   }
74
75   private void logNotifyAddWaitingStartTimer(int waiterCount, LockAwardContext ctxt) {
76     if (logger.isDebugEnabled()) {
77       logger.debug("notifyAddWaiting(waiterCount=" + waiterCount + ", ctxt=" + ctxt + "): starting lock timer...");
78     }
79   }
80
81   private void logNotifyAddWaitingUncontended(int waiterCount, LockAwardContext ctxt) {
82     if (logger.isDebugEnabled()) {
83       logger.debug("notifyAddWaiting(watierCount=" + waiterCount + ", ctxt=" + ctxt + "): adding to uncontended...");
84     }
85   }
86
87   /**
88    * If the waiter count is greater than zero, we should schedule a timeout for this lock award context. Otherwise, we
89    * shouldn't do anything.
90    */

91   public synchronized void notifyAward(int waiterCount, LockAwardContext ctxt) {
92     Assert.eval(waiterCount >= 0);
93     if (waiterCount > 0) {
94       logNotifyAwardStartTimer(waiterCount, ctxt);
95       startTimerForLock(ctxt);
96     } else {
97       logNotifyAwardUncontended(waiterCount, ctxt);
98       uncontended.add(ctxt);
99     }
100   }
101
102   private void logNotifyAwardStartTimer(int waiterCount, LockAwardContext ctxt) {
103     if (logger.isDebugEnabled()) {
104       logger.debug("notifyAward(waiterCount=" + waiterCount + ", ctxt=" + ctxt + "): starting lock timer...");
105     }
106   }
107
108   private void logNotifyAwardUncontended(int waiterCount, LockAwardContext ctxt) {
109     if (logger.isDebugEnabled()) {
110       logger.debug("notifyAward(waiterCount=" + waiterCount + ", ctxt=" + ctxt + "): adding to uncontended...");
111     }
112   }
113
114   /**
115    * We should cancel any existing timers for the given lock award context.
116    */

117   public synchronized void notifyRevoke(LockAwardContext ctxt) {
118     LockAwardContext cancelled = cancel(ctxt);
119     logNotifyRevoke(ctxt, cancelled);
120     if (cancelled == null) {
121       // check to make sure that it was uncontended
122
Assert.eval("Attempt to revoke a lock that was not awarded and not uncontended.", uncontended.remove(ctxt));
123     }
124   }
125
126   private void logNotifyRevoke(LockAwardContext ctxt, LockAwardContext cancelled) {
127     if (logger.isDebugEnabled()) {
128       logger.debug("notifyRevoke(ctxt=" + ctxt + "): cancelled=" + cancelled);
129     }
130   }
131
132   /*********************************************************************************************************************
133    * Private stuff.
134    */

135
136   private void putTimerTask(LockTimeoutTask task) {
137     synchronized (this.tasks) {
138       this.tasks.put(task.awardContext, task);
139     }
140   }
141
142   private LockTimeoutTask removeTimerTask(LockAwardContext awardContext) {
143     synchronized (this.tasks) {
144       return (LockTimeoutTask) this.tasks.remove(awardContext);
145     }
146   }
147
148   private void logStartTimerForLock(LockAwardContext awardContext) {
149     if (logger.isDebugEnabled()) {
150       logger.debug("startTimerForLock(" + awardContext + ")");
151     }
152   }
153
154   private void logCancel(LockAwardContext awardContext) {
155     if (logger.isDebugEnabled()) {
156       logger.debug("cancel(" + awardContext + ")");
157     }
158   }
159
160   private class LockTimeoutTask extends TimerTask JavaDoc {
161     private final LockAwardContext awardContext;
162
163     private LockTimeoutTask(LockAwardContext ctxt) {
164       Assert.assertNotNull(ctxt);
165       Assert.assertNotNull(ctxt.getChannelID());
166       this.awardContext = ctxt;
167     }
168
169     long getTimeout() {
170       return awardContext.getTimeout();
171     }
172
173     public void run() {
174       logger.warn("Lock timeout: " + this.awardContext);
175       try {
176         MessageChannel channel = channelManager.getActiveChannel(this.awardContext.getChannelID());
177         logger.warn("Closing channel because of lock timeout. Award context: " + this.awardContext + "; channel: "
178                     + channel);
179         channel.close();
180       } catch (NoSuchChannelException e) {
181         logger.warn("Attempting to close channel because of lock timeout. Couldn't find channel by channel id: "
182                     + this.awardContext.getChannelID());
183       }
184     }
185   }
186
187 }
Popular Tags