1 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 ; 16 import java.util.HashSet ; 17 import java.util.Map ; 18 import java.util.Set ; 19 import java.util.Timer ; 20 import java.util.TimerTask ; 21 22 25 public class LockTimer implements LockEventListener { 26 27 private static final TCLogger logger = TCLogging.getLogger(LockTimer.class); 28 29 private final Timer timer = new Timer (true); 30 private final DSOChannelManager channelManager; 31 private final Map tasks = new HashMap (); 32 private final Set uncontended = new HashSet (); 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 59 60 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 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 117 public synchronized void notifyRevoke(LockAwardContext ctxt) { 118 LockAwardContext cancelled = cancel(ctxt); 119 logNotifyRevoke(ctxt, cancelled); 120 if (cancelled == null) { 121 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 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 { 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 |