Simplifying code inside Utilities class by making ActiveQueue impl a separate class. release67_beta_base
authorJaroslav Tulach <jtulach@netbeans.org>
Tue, 07 Apr 2009 11:31:38 +0200
changeset 53036fcbe493ff7
parent 529 92a0f73a01c3
child 531 930872d0e080
child 751 8b29a6112c6a
child 904 aa6cb587e3fe
Simplifying code inside Utilities class by making ActiveQueue impl a separate class.
Making AbstractLookup less dependent on the other features of Utilities class.
openide.util/src/org/netbeans/modules/openide/util/ActiveQueue.java
openide.util/src/org/openide/util/Utilities.java
openide.util/src/org/openide/util/lookup/AbstractLookup.java
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/openide.util/src/org/netbeans/modules/openide/util/ActiveQueue.java	Tue Apr 07 11:31:38 2009 +0200
     1.3 @@ -0,0 +1,108 @@
     1.4 +package org.netbeans.modules.openide.util;
     1.5 +
     1.6 +import java.lang.ref.Reference;
     1.7 +import java.lang.ref.ReferenceQueue;
     1.8 +import java.util.logging.Level;
     1.9 +import java.util.logging.Logger;
    1.10 +
    1.11 +/**
    1.12 + * Implementation of the active reference queue.
    1.13 + */
    1.14 +public final class ActiveQueue extends ReferenceQueue<Object> implements Runnable {
    1.15 +
    1.16 +    private static final Logger LOGGER = Logger.getLogger(ActiveQueue.class.getName().replace('$', '.'));
    1.17 +    private static ActiveQueue activeReferenceQueue;
    1.18 +    
    1.19 +    /** number of known outstanding references */
    1.20 +    private int count;
    1.21 +    private boolean deprecated;
    1.22 +
    1.23 +    ActiveQueue(boolean deprecated) {
    1.24 +        super();
    1.25 +        this.deprecated = deprecated;
    1.26 +    }
    1.27 +
    1.28 +    public static synchronized ReferenceQueue<Object> queue() {
    1.29 +        if (activeReferenceQueue == null) {
    1.30 +            activeReferenceQueue = new ActiveQueue(false);
    1.31 +        }
    1.32 +
    1.33 +        activeReferenceQueue.ping();
    1.34 +
    1.35 +        return activeReferenceQueue;
    1.36 +    }
    1.37 +
    1.38 +    @Override
    1.39 +    public Reference<Object> poll() {
    1.40 +        throw new UnsupportedOperationException();
    1.41 +    }
    1.42 +
    1.43 +    @Override
    1.44 +    public Reference<Object> remove(long timeout) throws IllegalArgumentException, InterruptedException {
    1.45 +        throw new InterruptedException();
    1.46 +    }
    1.47 +
    1.48 +    @Override
    1.49 +    public Reference<Object> remove() throws InterruptedException {
    1.50 +        throw new InterruptedException();
    1.51 +    }
    1.52 +
    1.53 +    public void run() {
    1.54 +        while (true) {
    1.55 +            try {
    1.56 +                Reference<?> ref = super.remove(0);
    1.57 +                LOGGER.finer("dequeued reference");
    1.58 +                if (!(ref instanceof Runnable)) {
    1.59 +                    LOGGER.warning("A reference not implementing runnable has been added to the Utilities.activeReferenceQueue(): " + ref.getClass());
    1.60 +                    continue;
    1.61 +                }
    1.62 +                if (deprecated) {
    1.63 +                    LOGGER.warning("Utilities.ACTIVE_REFERENCE_QUEUE has been deprecated for " + ref.getClass() + " use Utilities.activeReferenceQueue");
    1.64 +                }
    1.65 +                // do the cleanup
    1.66 +                try {
    1.67 +                    ((Runnable) ref).run();
    1.68 +                } catch (ThreadDeath td) {
    1.69 +                    throw td;
    1.70 +                } catch (Throwable t) {
    1.71 +                    // Should not happen.
    1.72 +                    // If it happens, it is a bug in client code, notify!
    1.73 +                    LOGGER.log(Level.WARNING, null, t);
    1.74 +                } finally {
    1.75 +                    // to allow GC
    1.76 +                    ref = null;
    1.77 +                }
    1.78 +            } catch (InterruptedException ex) {
    1.79 +                // Can happen during VM shutdown, it seems. Ignore.
    1.80 +                continue;
    1.81 +            }
    1.82 +            synchronized (this) {
    1.83 +                assert count > 0;
    1.84 +                count--;
    1.85 +                if (count == 0) {
    1.86 +                    // We have processed all we have to process (for now at least).
    1.87 +                    // Could be restarted later if ping() called again.
    1.88 +                    // This could also happen in case someone called queue() once and tried
    1.89 +                    // to use it for several references; in that case run() might never be called on
    1.90 +                    // the later ones to be collected. Can't really protect against that situation.
    1.91 +                    // See issue #86625 for details.
    1.92 +                    LOGGER.fine("stopping thread");
    1.93 +                    break;
    1.94 +                }
    1.95 +            }
    1.96 +        }
    1.97 +    }
    1.98 +
    1.99 +    synchronized void ping() {
   1.100 +        if (count == 0) {
   1.101 +            Thread t = new Thread(this, "Active Reference Queue Daemon");
   1.102 +            t.setPriority(Thread.MIN_PRIORITY);
   1.103 +            t.setDaemon(true);
   1.104 +            t.start();
   1.105 +            LOGGER.fine("starting thread");
   1.106 +        } else {
   1.107 +            LOGGER.finer("enqueuing reference");
   1.108 +        }
   1.109 +        count++;
   1.110 +    }
   1.111 +}
     2.1 --- a/openide.util/src/org/openide/util/Utilities.java	Tue Apr 07 00:37:21 2009 +0400
     2.2 +++ b/openide.util/src/org/openide/util/Utilities.java	Tue Apr 07 11:31:38 2009 +0200
     2.3 @@ -41,6 +41,7 @@
     2.4  
     2.5  package org.openide.util;
     2.6  
     2.7 +import org.netbeans.modules.openide.util.ActiveQueue;
     2.8  import java.awt.BorderLayout;
     2.9  import java.awt.Component;
    2.10  import java.awt.Container;
    2.11 @@ -211,8 +212,6 @@
    2.12      /** A height of the Mac OS X's menu */
    2.13      private static final int TYPICAL_MACOSX_MENU_HEIGHT = 24;
    2.14  
    2.15 -    private static ActiveQueue activeReferenceQueue;
    2.16 -
    2.17      /** The operating system on which NetBeans runs*/
    2.18      private static int operatingSystem = -1;
    2.19      private static final String[] keywords = new String[] {
    2.20 @@ -271,7 +270,7 @@
    2.21       * class MyReference extends WeakReference<Thing> implements Runnable {
    2.22       *     private final OtherInfo dataToCleanUp;
    2.23       *     public MyReference(Thing ref, OtherInfo data) {
    2.24 -     *         super(ref, Utilities.activeReferenceQueue());
    2.25 +     *         super(ref, Utilities.queue());
    2.26       *         dataToCleanUp = data;
    2.27       *     }
    2.28       *     public void run() {
    2.29 @@ -293,14 +292,8 @@
    2.30       * Do not attempt to cache the return value.
    2.31       * @since 3.11
    2.32       */
    2.33 -    public static synchronized ReferenceQueue<Object> activeReferenceQueue() {
    2.34 -        if (activeReferenceQueue == null) {
    2.35 -            activeReferenceQueue = new ActiveQueue(false);
    2.36 -        }
    2.37 -
    2.38 -        activeReferenceQueue.ping();
    2.39 -
    2.40 -        return activeReferenceQueue;
    2.41 +    public static ReferenceQueue<Object> activeReferenceQueue() {
    2.42 +        return ActiveQueue.queue();
    2.43      }
    2.44  
    2.45      /** Get the operating system on which NetBeans is running.
    2.46 @@ -3117,107 +3110,4 @@
    2.47              return deps;
    2.48          }
    2.49      }
    2.50 -
    2.51 -    /** Implementation of the active queue.
    2.52 -     */
    2.53 -    private static final class ActiveQueue extends ReferenceQueue<Object> implements Runnable {
    2.54 -
    2.55 -        private static final Logger LOGGER = Logger.getLogger(ActiveQueue.class.getName().replace('$', '.'));
    2.56 -
    2.57 -        /** number of known outstanding references */
    2.58 -        private int count;
    2.59 -        private boolean deprecated;
    2.60 -
    2.61 -        public ActiveQueue(boolean deprecated) {
    2.62 -            this.deprecated = deprecated;
    2.63 -        }
    2.64 -
    2.65 -        @Override
    2.66 -        public Reference<Object> poll() {
    2.67 -            throw new UnsupportedOperationException();
    2.68 -        }
    2.69 -
    2.70 -        @Override
    2.71 -        public Reference<Object> remove(long timeout) throws IllegalArgumentException, InterruptedException {
    2.72 -            throw new InterruptedException();
    2.73 -        }
    2.74 -
    2.75 -        @Override
    2.76 -        public Reference<Object> remove() throws InterruptedException {
    2.77 -            throw new InterruptedException();
    2.78 -        }
    2.79 -
    2.80 -        public void run() {
    2.81 -            while (true) {
    2.82 -                try {
    2.83 -                    Reference<?> ref = super.remove(0);
    2.84 -                    LOGGER.finer("dequeued reference");
    2.85 -
    2.86 -                    if (!(ref instanceof Runnable)) {
    2.87 -                        LOGGER.warning(
    2.88 -                            "A reference not implementing runnable has been added to the Utilities.activeReferenceQueue(): " +
    2.89 -                            ref.getClass() // NOI18N
    2.90 -                        );
    2.91 -
    2.92 -                        continue;
    2.93 -                    }
    2.94 -
    2.95 -                    if (deprecated) {
    2.96 -                        LOGGER.warning(
    2.97 -                            "Utilities.ACTIVE_REFERENCE_QUEUE has been deprecated for " + ref.getClass() +
    2.98 -                            " use Utilities.activeReferenceQueue" // NOI18N
    2.99 -                        );
   2.100 -                    }
   2.101 -
   2.102 -                    // do the cleanup
   2.103 -                    try {
   2.104 -                        ((Runnable) ref).run();
   2.105 -                    } catch (ThreadDeath td) {
   2.106 -                        throw td;
   2.107 -                    } catch (Throwable t) {
   2.108 -                        // Should not happen.
   2.109 -                        // If it happens, it is a bug in client code, notify!
   2.110 -                        LOGGER.log(Level.WARNING, null, t);
   2.111 -                    } finally {
   2.112 -                        // to allow GC
   2.113 -                        ref = null;
   2.114 -                    }
   2.115 -                } catch (InterruptedException ex) {
   2.116 -                    // Can happen during VM shutdown, it seems. Ignore.
   2.117 -                    continue;
   2.118 -                }
   2.119 -
   2.120 -                synchronized (this) {
   2.121 -                    assert count > 0;
   2.122 -                    count--;
   2.123 -                    if (count == 0) {
   2.124 -                        // We have processed all we have to process (for now at least).
   2.125 -                        // Could be restarted later if ping() called again.
   2.126 -                        // This could also happen in case someone called activeReferenceQueue() once and tried
   2.127 -                        // to use it for several references; in that case run() might never be called on
   2.128 -                        // the later ones to be collected. Can't really protect against that situation.
   2.129 -                        // See issue #86625 for details.
   2.130 -                        LOGGER.fine("stopping thread");
   2.131 -                        break;
   2.132 -                    }
   2.133 -                }
   2.134 -            }
   2.135 -        }
   2.136 -
   2.137 -        synchronized void ping() {
   2.138 -            if (count == 0) {
   2.139 -                Thread t = new Thread(this, "Active Reference Queue Daemon"); // NOI18N
   2.140 -                t.setPriority(Thread.MIN_PRIORITY);
   2.141 -                t.setDaemon(true); // to not prevent exit of VM
   2.142 -                t.start();
   2.143 -                // Note that this will not be printed during IDE startup because
   2.144 -                // it happens before logging is even initialized.
   2.145 -                LOGGER.fine("starting thread");
   2.146 -            } else {
   2.147 -                LOGGER.finer("enqueuing reference");
   2.148 -            }
   2.149 -            count++;
   2.150 -        }
   2.151 -
   2.152 -    }
   2.153  }
     3.1 --- a/openide.util/src/org/openide/util/lookup/AbstractLookup.java	Tue Apr 07 00:37:21 2009 +0400
     3.2 +++ b/openide.util/src/org/openide/util/lookup/AbstractLookup.java	Tue Apr 07 11:31:38 2009 +0200
     3.3 @@ -64,7 +64,7 @@
     3.4  import java.util.TreeSet;
     3.5  
     3.6  import java.util.concurrent.Executor;
     3.7 -import org.openide.util.Utilities;
     3.8 +import org.netbeans.modules.openide.util.ActiveQueue;
     3.9  
    3.10  
    3.11  /** Implementation of the lookup from OpenAPIs that is based on the
    3.12 @@ -687,7 +687,7 @@
    3.13      }
    3.14  
    3.15      private static ReferenceQueue<Object> activeQueue() {
    3.16 -        return Utilities.activeReferenceQueue();
    3.17 +        return ActiveQueue.queue();
    3.18      }
    3.19  
    3.20      /** Storage to keep the internal structure of Pairs and to answer