001    /* 
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     *
017     */
018    
019    package org.apache.commons.exec;
020    
021    import java.util.Enumeration;
022    import java.util.Vector;
023    
024    /**
025     * Generalization of <code>ExecuteWatchdog</code>
026     * 
027     * @see org.apache.commons.exec.ExecuteWatchdog
028     */
029    public class Watchdog implements Runnable {
030    
031        private Vector observers = new Vector(1);
032    
033        private final long timeout;
034    
035        private boolean stopped = false;
036    
037        public Watchdog(final long timeout) {
038            if (timeout < 1) {
039                throw new IllegalArgumentException("timeout must not be less than 1.");
040            }
041            this.timeout = timeout;
042        }
043    
044        public void addTimeoutObserver(final TimeoutObserver to) {
045            observers.addElement(to);
046        }
047    
048        public void removeTimeoutObserver(final TimeoutObserver to) {
049            observers.removeElement(to);
050        }
051    
052        protected final void fireTimeoutOccured() {
053            Enumeration e = observers.elements();
054            while (e.hasMoreElements()) {
055                ((TimeoutObserver) e.nextElement()).timeoutOccured(this);
056            }
057        }
058    
059        public synchronized void start() {
060            stopped = false;
061            Thread t = new Thread(this, "WATCHDOG");
062            t.setDaemon(true);
063            t.start();
064        }
065    
066        public synchronized void stop() {
067            stopped = true;
068            notifyAll();
069        }
070    
071        public synchronized void run() {
072            final long until = System.currentTimeMillis() + timeout;
073            long now;
074            while (!stopped && until > (now = System.currentTimeMillis())) {
075                try {
076                    wait(until - now);
077                } catch (InterruptedException e) {
078                }
079            }
080            if (!stopped) {
081                fireTimeoutOccured();
082            }
083        }
084    }