src/share/classes/java/util/logging/LogManager.java

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this

@@ -476,10 +476,16 @@
             WeakReference<Logger> nodeRef = nodep.loggerRef;
             if (nodeRef != null) {
                 parent = nodeRef.get();
                 if (parent != null) {
                     break;
+                } else {
+                    // nodep holds a stale weak reference to a Logger
+                    // which has been GC-ed. Note this will only cleanup
+                    // stale weak refs that we encounter before we find
+                    // our parent LogNode.
+                    nodep.loggerRef = null;
                 }
             }
             nodep = nodep.parent;
         }
 

@@ -487,10 +493,20 @@
             doSetParent(logger, parent);
         }
         // Walk over the children and tell them we are their new parent.
         node.walkAndSetParent(logger);
 
+        if (node.parent != null) {
+            // Look for possible weak reference cleanup from the new
+            // parent LogNode down. The walkAndSetParent() call above
+            // might have already done some or none of this work so
+            // this call is the only way to be absolutely sure we have
+            // checked for stale weak refs in every LogNode in the
+            // parent LogNode's hierarchy.
+            node.parent.deleteStaleWeakRefs();
+        }
+
         return true;
     }
 
 
     // Private method to set a level on a logger.

@@ -959,16 +975,42 @@
             while (values.hasNext()) {
                 LogNode node = values.next();
                 WeakReference<Logger> ref = node.loggerRef;
                 Logger logger = (ref == null) ? null : ref.get();
                 if (logger == null) {
+                    // node holds a stale weak reference to a Logger
+                    // which has been GC-ed. Note this will only cleanup
+                    // stale weak refs that we encounter during our walk
+                    // from the original node.
+                    node.loggerRef = null;
                     node.walkAndSetParent(parent);
                 } else {
                     doSetParent(logger, parent);
                 }
             }
         }
+
+        // Recursively delete stale WeakReferences on each of our children.
+        void deleteStaleWeakRefs() {
+            if (children == null) {
+                return;
+            }
+            Iterator<LogNode> values = children.values().iterator();
+            while (values.hasNext()) {
+                LogNode node = values.next();
+                WeakReference<Logger> ref = node.loggerRef;
+                if (ref != null) {
+                    Logger logger = ref.get();
+                    if (logger == null) {
+                        // node holds a stale weak reference to a Logger
+                        // which has been GC-ed.
+                        node.loggerRef = null;
+                    }
+                }
+                node.deleteStaleWeakRefs();
+            }
+        }
     }
 
     // We use a subclass of Logger for the root logger, so
     // that we only instantiate the global handlers when they
     // are first needed.