13742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman// Licensed under Apache License version 2.0
23742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanpackage javax.jmdns.impl;
33742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
43742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.Collection;
53742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.concurrent.ConcurrentHashMap;
63742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.concurrent.ConcurrentMap;
73742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.concurrent.Semaphore;
83742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.concurrent.TimeUnit;
93742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.concurrent.locks.ReentrantLock;
103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.logging.Level;
113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.logging.Logger;
123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.impl.constants.DNSState;
143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.impl.tasks.DNSTask;
153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman/**
173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Sets of methods to manage the state machine.<br/>
183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * <b>Implementation note:</b> This interface is accessed from multiple threads. The implementation must be thread safe.
193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman *
203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @author Pierre Frisch
213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */
223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanpublic interface DNSStatefulObject {
233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /**
253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * This class define a semaphore. On this multiple threads can wait the arrival of one event. Thread wait for a maximum defined by the timeout.
263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * <p>
273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * Implementation note: this class is based on {@link java.util.concurrent.Semaphore} so that they can be released by the timeout timer.
283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * </p>
293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *
303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @author Pierre Frisch
313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public static final class DNSStatefulObjectSemaphore {
333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        private static Logger                          logger = Logger.getLogger(DNSStatefulObjectSemaphore.class.getName());
343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        private final String                           _name;
363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        private final ConcurrentMap<Thread, Semaphore> _semaphores;
383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * @param name
413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         *            Semaphore name for debugging purposes.
423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public DNSStatefulObjectSemaphore(String name) {
443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            super();
453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            _name = name;
463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            _semaphores = new ConcurrentHashMap<Thread, Semaphore>(50);
473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * Blocks the current thread until the event arrives or the timeout expires.
513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         *
523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * @param timeout
533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         *            wait period for the event
543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public void waitForEvent(long timeout) {
563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            Thread thread = Thread.currentThread();
573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            Semaphore semaphore = _semaphores.get(thread);
583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            if (semaphore == null) {
593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                semaphore = new Semaphore(1, true);
603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                semaphore.drainPermits();
613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                _semaphores.putIfAbsent(thread, semaphore);
623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            }
633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            semaphore = _semaphores.get(thread);
643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            try {
653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                semaphore.tryAcquire(timeout, TimeUnit.MILLISECONDS);
663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            } catch (InterruptedException exception) {
673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                logger.log(Level.FINER, "Exception ", exception);
683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            }
693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * Signals the semaphore when the event arrives.
733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public void signalEvent() {
753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            Collection<Semaphore> semaphores = _semaphores.values();
763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            for (Semaphore semaphore : semaphores) {
773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                semaphore.release();
783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                semaphores.remove(semaphore);
793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            }
803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        @Override
833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public String toString() {
843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            StringBuilder aLog = new StringBuilder(1000);
853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            aLog.append("Semaphore: ");
863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            aLog.append(this._name);
873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            if (_semaphores.size() == 0) {
883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                aLog.append(" no semaphores.");
893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            } else {
903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                aLog.append(" semaphores:\n");
913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                for (Thread thread : _semaphores.keySet()) {
923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    aLog.append("\tThread: ");
933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    aLog.append(thread.getName());
943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    aLog.append(' ');
953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    aLog.append(_semaphores.get(thread));
963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    aLog.append('\n');
973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                }
983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            }
993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            return aLog.toString();
1003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
1013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
1023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    }
1033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
1043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public static class DefaultImplementation extends ReentrantLock implements DNSStatefulObject {
1053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        private static Logger                    logger           = Logger.getLogger(DefaultImplementation.class.getName());
1063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
1073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        private static final long                serialVersionUID = -3264781576883412227L;
1083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
1093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        private volatile JmDNSImpl               _dns;
1103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
1113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        protected volatile DNSTask               _task;
1123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
1133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        protected volatile DNSState              _state;
1143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
1153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        private final DNSStatefulObjectSemaphore _announcing;
1163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
1173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        private final DNSStatefulObjectSemaphore _canceling;
1183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
1193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public DefaultImplementation() {
1203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            super();
1213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            _dns = null;
1223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            _task = null;
1233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            _state = DNSState.PROBING_1;
1243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            _announcing = new DNSStatefulObjectSemaphore("Announce");
1253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            _canceling = new DNSStatefulObjectSemaphore("Cancel");
1263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
1273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
1283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
1293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * {@inheritDoc}
1303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
1313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        @Override
1323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public JmDNSImpl getDns() {
1333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            return this._dns;
1343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
1353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
1363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        protected void setDns(JmDNSImpl dns) {
1373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            this._dns = dns;
1383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
1393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
1403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
1413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * {@inheritDoc}
1423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
1433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        @Override
1443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public void associateWithTask(DNSTask task, DNSState state) {
1453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            if (this._task == null && this._state == state) {
1463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                this.lock();
1473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                try {
1483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    if (this._task == null && this._state == state) {
1493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                        this.setTask(task);
1503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    }
1513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                } finally {
1523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    this.unlock();
1533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                }
1543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            }
1553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
1563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
1573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
1583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * {@inheritDoc}
1593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
1603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        @Override
1613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public void removeAssociationWithTask(DNSTask task) {
1623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            if (this._task == task) {
1633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                this.lock();
1643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                try {
1653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    if (this._task == task) {
1663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                        this.setTask(null);
1673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    }
1683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                } finally {
1693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    this.unlock();
1703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                }
1713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            }
1723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
1733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
1743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
1753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * {@inheritDoc}
1763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
1773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        @Override
1783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public boolean isAssociatedWithTask(DNSTask task, DNSState state) {
1793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            this.lock();
1803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            try {
1813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                return this._task == task && this._state == state;
1823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            } finally {
1833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                this.unlock();
1843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            }
1853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
1863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
1873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        protected void setTask(DNSTask task) {
1883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            this._task = task;
1893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
1903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
1913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
1923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * @param state
1933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         *            the state to set
1943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
1953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        protected void setState(DNSState state) {
1963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            this.lock();
1973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            try {
1983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                this._state = state;
1993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                if (this.isAnnounced()) {
2003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    _announcing.signalEvent();
2013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                }
2023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                if (this.isCanceled()) {
2033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    _canceling.signalEvent();
2043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    // clear any waiting announcing
2053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    _announcing.signalEvent();
2063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                }
2073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            } finally {
2083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                this.unlock();
2093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            }
2103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
2113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
2123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
2133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * {@inheritDoc}
2143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
2153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        @Override
2163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public boolean advanceState(DNSTask task) {
2173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            boolean result = true;
2183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            if (this._task == task) {
2193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                this.lock();
2203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                try {
2213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    if (this._task == task) {
2223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                        this.setState(this._state.advance());
2233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    } else {
2243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                        logger.warning("Trying to advance state whhen not the owner. owner: " + this._task + " perpetrator: " + task);
2253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    }
2263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                } finally {
2273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    this.unlock();
2283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                }
2293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            }
2303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            return result;
2313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
2323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
2333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
2343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * {@inheritDoc}
2353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
2363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        @Override
2373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public boolean revertState() {
2383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            boolean result = true;
2393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            if (!this.willCancel()) {
2403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                this.lock();
2413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                try {
2423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    if (!this.willCancel()) {
2433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                        this.setState(this._state.revert());
2443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                        this.setTask(null);
2453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    }
2463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                } finally {
2473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    this.unlock();
2483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                }
2493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            }
2503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            return result;
2513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
2523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
2533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
2543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * {@inheritDoc}
2553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
2563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        @Override
2573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public boolean cancelState() {
2583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            boolean result = false;
2593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            if (!this.willCancel()) {
2603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                this.lock();
2613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                try {
2623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    if (!this.willCancel()) {
2633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                        this.setState(DNSState.CANCELING_1);
2643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                        this.setTask(null);
2653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                        result = true;
2663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    }
2673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                } finally {
2683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    this.unlock();
2693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                }
2703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            }
2713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            return result;
2723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
2733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
2743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
2753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * {@inheritDoc}
2763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
2773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        @Override
2783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public boolean closeState() {
2793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            boolean result = false;
2803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            if (!this.willClose()) {
2813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                this.lock();
2823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                try {
2833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    if (!this.willClose()) {
2843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                        this.setState(DNSState.CLOSING);
2853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                        this.setTask(null);
2863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                        result = true;
2873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    }
2883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                } finally {
2893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    this.unlock();
2903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                }
2913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            }
2923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            return result;
2933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
2943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
2953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
2963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * {@inheritDoc}
2973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
2983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        @Override
2993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public boolean recoverState() {
3003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            boolean result = false;
3013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            this.lock();
3023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            try {
3033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                this.setState(DNSState.PROBING_1);
3043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                this.setTask(null);
3053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            } finally {
3063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                this.unlock();
3073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            }
3083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            return result;
3093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
3103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
3113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
3123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * {@inheritDoc}
3133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
3143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        @Override
3153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public boolean isProbing() {
3163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            return this._state.isProbing();
3173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
3183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
3193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
3203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * {@inheritDoc}
3213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
3223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        @Override
3233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public boolean isAnnouncing() {
3243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            return this._state.isAnnouncing();
3253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
3263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
3273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
3283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * {@inheritDoc}
3293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
3303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        @Override
3313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public boolean isAnnounced() {
3323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            return this._state.isAnnounced();
3333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
3343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
3353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
3363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * {@inheritDoc}
3373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
3383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        @Override
3393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public boolean isCanceling() {
3403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            return this._state.isCanceling();
3413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
3423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
3433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
3443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * {@inheritDoc}
3453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
3463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        @Override
3473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public boolean isCanceled() {
3483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            return this._state.isCanceled();
3493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
3503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
3513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
3523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * {@inheritDoc}
3533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
3543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        @Override
3553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public boolean isClosing() {
3563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            return this._state.isClosing();
3573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
3583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
3593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
3603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * {@inheritDoc}
3613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
3623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        @Override
3633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public boolean isClosed() {
3643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            return this._state.isClosed();
3653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
3663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
3673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        private boolean willCancel() {
3683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            return this._state.isCanceled() || this._state.isCanceling();
3693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
3703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
3713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        private boolean willClose() {
3723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            return this._state.isClosed() || this._state.isClosing();
3733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
3743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
3753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
3763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * {@inheritDoc}
3773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
3783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        @Override
3793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public boolean waitForAnnounced(long timeout) {
3803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            if (!this.isAnnounced() && !this.willCancel()) {
3813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                _announcing.waitForEvent(timeout);
3823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            }
3833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            if (!this.isAnnounced()) {
3843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                if (this.willCancel() || this.willClose()) {
3853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    logger.fine("Wait for announced cancelled: " + this);
3863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                } else {
3873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    logger.warning("Wait for announced timed out: " + this);
3883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                }
3893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            }
3903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            return this.isAnnounced();
3913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
3923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
3933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
3943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * {@inheritDoc}
3953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
3963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        @Override
3973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public boolean waitForCanceled(long timeout) {
3983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            if (!this.isCanceled()) {
3993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                _canceling.waitForEvent(timeout);
4003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            }
4013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            if (!this.isCanceled() && !this.willClose()) {
4023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                logger.warning("Wait for canceled timed out: " + this);
4033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            }
4043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            return this.isCanceled();
4053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
4063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
4073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        /**
4083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         * {@inheritDoc}
4093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman         */
4103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        @Override
4113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        public String toString() {
4123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            return (_dns != null ? "DNS: " + _dns.getName() : "NO DNS") + " state: " + _state + " task: " + _task;
4133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
4143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
4153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    }
4163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
4173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /**
4183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * Returns the DNS associated with this object.
4193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *
4203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @return DNS resolver
4213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
4223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public JmDNSImpl getDns();
4233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
4243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /**
4253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * Sets the task associated with this Object.
4263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *
4273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @param task
4283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *            associated task
4293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @param state
4303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *            state of the task
4313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
4323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public void associateWithTask(DNSTask task, DNSState state);
4333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
4343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /**
4353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * Remove the association of the task with this Object.
4363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *
4373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @param task
4383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *            associated task
4393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
4403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public void removeAssociationWithTask(DNSTask task);
4413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
4423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /**
4433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * Checks if this object is associated with the task and in the same state.
4443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *
4453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @param task
4463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *            associated task
4473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @param state
4483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *            state of the task
4493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @return <code>true</code> is the task is associated with this object, <code>false</code> otherwise.
4503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
4513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public boolean isAssociatedWithTask(DNSTask task, DNSState state);
4523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
4533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /**
4543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * Sets the state and notifies all objects that wait on the ServiceInfo.
4553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *
4563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @param task
4573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *            associated task
4583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @return <code>true</code if the state was changed by this thread, <code>false</code> otherwise.
4593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @see DNSState#advance()
4603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
4613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public boolean advanceState(DNSTask task);
4623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
4633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /**
4643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * Sets the state and notifies all objects that wait on the ServiceInfo.
4653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *
4663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @return <code>true</code if the state was changed by this thread, <code>false</code> otherwise.
4673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @see DNSState#revert()
4683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
4693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public boolean revertState();
4703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
4713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /**
4723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * Sets the state and notifies all objects that wait on the ServiceInfo.
4733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *
4743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @return <code>true</code if the state was changed by this thread, <code>false</code> otherwise.
4753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
4763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public boolean cancelState();
4773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
4783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /**
4793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * Sets the state and notifies all objects that wait on the ServiceInfo.
4803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *
4813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @return <code>true</code if the state was changed by this thread, <code>false</code> otherwise.
4823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
4833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public boolean closeState();
4843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
4853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /**
4863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * Sets the state and notifies all objects that wait on the ServiceInfo.
4873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *
4883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @return <code>true</code if the state was changed by this thread, <code>false</code> otherwise.
4893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
4903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public boolean recoverState();
4913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
4923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /**
4933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * Returns true, if this is a probing state.
4943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *
4953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @return <code>true</code> if probing state, <code>false</code> otherwise
4963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
4973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public boolean isProbing();
4983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
4993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /**
5003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * Returns true, if this is an announcing state.
5013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *
5023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @return <code>true</code> if announcing state, <code>false</code> otherwise
5033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
5043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public boolean isAnnouncing();
5053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
5063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /**
5073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * Returns true, if this is an announced state.
5083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *
5093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @return <code>true</code> if announced state, <code>false</code> otherwise
5103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
5113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public boolean isAnnounced();
5123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
5133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /**
5143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * Returns true, if this is a canceling state.
5153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *
5163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @return <code>true</code> if canceling state, <code>false</code> otherwise
5173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
5183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public boolean isCanceling();
5193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
5203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /**
5213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * Returns true, if this is a canceled state.
5223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *
5233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @return <code>true</code> if canceled state, <code>false</code> otherwise
5243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
5253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public boolean isCanceled();
5263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
5273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /**
5283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * Returns true, if this is a closing state.
5293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *
5303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @return <code>true</code> if closing state, <code>false</code> otherwise
5313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
5323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public boolean isClosing();
5333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
5343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /**
5353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * Returns true, if this is a closed state.
5363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *
5373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @return <code>true</code> if closed state, <code>false</code> otherwise
5383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
5393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public boolean isClosed();
5403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
5413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /**
5423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * Waits for the object to be announced.
5433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *
5443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @param timeout
5453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *            the maximum time to wait in milliseconds.
5463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @return <code>true</code> if the object is announced, <code>false</code> otherwise
5473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
5483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public boolean waitForAnnounced(long timeout);
5493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
5503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /**
5513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * Waits for the object to be canceled.
5523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *
5533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @param timeout
5543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *            the maximum time to wait in milliseconds.
5553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @return <code>true</code> if the object is canceled, <code>false</code> otherwise
5563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
5573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public boolean waitForCanceled(long timeout);
5583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
5593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman}
560