1 17 18 package org.apache.james.util.watchdog; 19 20 import org.apache.avalon.excalibur.thread.ThreadPool; 21 import org.apache.avalon.framework.activity.Disposable; 22 import org.apache.avalon.framework.logger.AbstractLogEnabled; 23 24 33 public class InaccurateTimeoutWatchdog 34 extends AbstractLogEnabled 35 implements Watchdog, Runnable , Disposable { 36 37 40 private volatile boolean isChecking = false; 41 42 45 private volatile boolean isReset = false; 46 47 48 51 private final long timeout; 52 53 57 private volatile long lastReset; 58 59 63 private WatchdogTarget triggerTarget; 64 65 68 private Thread watchdogThread; 69 70 73 private ThreadPool myThreadPool; 74 75 82 public InaccurateTimeoutWatchdog(long timeout, WatchdogTarget target, ThreadPool threadPool) { 83 if (target == null) { 84 throw new IllegalArgumentException ("The WatchdogTarget for this TimeoutWatchdog cannot be null."); 85 } 86 if (threadPool == null) { 87 throw new IllegalArgumentException ("The thread pool for this TimeoutWatchdog cannot be null."); 88 } 89 this.timeout = timeout; 90 triggerTarget = target; 91 myThreadPool = threadPool; 92 } 93 94 97 public void start() { 98 getLogger().debug("Calling start()"); 99 lastReset = System.currentTimeMillis(); 100 isChecking = true; 101 synchronized(this) { 102 if ( watchdogThread == null) { 103 myThreadPool.execute(this); 104 } 105 } 106 } 107 108 112 public void reset() { 113 if (watchdogThread != null) { 114 getLogger().debug("Calling reset() " + watchdogThread.getName()); 115 } else { 116 getLogger().debug("Calling reset() for inactive watchdog"); 117 } 118 isReset = true; 119 } 120 121 125 public void stop() { 126 if (watchdogThread != null) { 127 getLogger().debug("Calling stop() " + watchdogThread.getName()); 128 } else { 129 getLogger().debug("Calling stop() for inactive watchdog"); 130 } 131 isChecking = false; 132 } 133 134 137 public void run() { 138 139 try { 140 watchdogThread = Thread.currentThread(); 141 142 while ((!(Thread.currentThread().interrupted())) && (watchdogThread != null)) { 143 try { 144 if (!isChecking) { 145 if (getLogger().isDebugEnabled()) { 146 getLogger().debug("Watchdog " + Thread.currentThread().getName() + " is not active - going to exit."); 147 } 148 synchronized (this) { 149 if (!isChecking) { 150 watchdogThread = null; 151 } 152 continue; 153 } 154 } else { 155 long currentTime = System.currentTimeMillis(); 156 if (isReset) { 157 isReset = false; 158 lastReset = currentTime; 159 } 160 long timeToSleep = lastReset + timeout - currentTime; 161 if (watchdogThread != null) { 162 getLogger().debug("Watchdog " + watchdogThread.getName() + " has time to sleep " + timeToSleep); 163 } else { 164 getLogger().debug("Watchdog has time to sleep " + timeToSleep); 165 } 166 if (timeToSleep <= 0) { 167 try { 168 synchronized (this) { 169 if ((isChecking) && (triggerTarget != null)) { 170 triggerTarget.execute(); 171 } 172 watchdogThread = null; 173 } 174 } catch (Throwable t) { 175 getLogger().error("Encountered error while executing Watchdog target.", t); 176 } 177 isChecking = false; 178 continue; 179 } else { 180 synchronized(this) { 181 wait(timeToSleep); 182 } 183 } 184 } 185 } catch (InterruptedException ie) { 186 } 187 } 188 189 synchronized( this ) { 190 watchdogThread = null; 191 } 192 } finally { 193 Thread.currentThread().interrupted(); 196 } 197 getLogger().debug("Watchdog " + Thread.currentThread().getName() + " is exiting run()."); 198 } 199 200 203 public void dispose() { 204 synchronized(this) { 205 isChecking = false; 206 if (watchdogThread != null) { 207 getLogger().debug("Calling disposeWatchdog() " + watchdogThread.getName()); 208 } else { 209 getLogger().debug("Calling disposeWatchdog() for inactive watchdog"); 210 } 211 if (watchdogThread != null) { 212 watchdogThread = null; 213 notifyAll(); 214 } 215 if (triggerTarget instanceof Disposable) { 216 ((Disposable)triggerTarget).dispose(); 217 } 218 triggerTarget = null; 219 } 220 } 221 } 222 | Popular Tags |