[jboss-cvs] JBossAS SVN: r90788 - projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Jul 2 16:55:01 EDT 2009


Author: david.lloyd at jboss.com
Date: 2009-07-02 16:55:01 -0400 (Thu, 02 Jul 2009)
New Revision: 90788

Modified:
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFS.java
Log:
Add explicit mountpoint cleanup code

Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFS.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFS.java	2009-07-02 20:21:22 UTC (rev 90787)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFS.java	2009-07-02 20:55:01 UTC (rev 90788)
@@ -48,7 +48,7 @@
    /** The log */
    private static final Logger log = Logger.getLogger(VFS.class);
 
-   private final MountNode rootMountNode = new MountNode();
+   private final MountNode rootMountNode = new MountNode(null);
    private final VirtualFile rootVirtualFile;
    private static VFS instance = new VFS();
 
@@ -123,7 +123,7 @@
             MountNode subNode;
             if (childMap == null) {
                childMap = new HashMap<String, MountNode>();
-               subNode = new MountNode();
+               subNode = new MountNode(mountNode);
                childMap.put(seg, subNode);
                mountNode.nodeMap = childMap;
                mountNode = subNode;
@@ -133,7 +133,7 @@
                   mountNode = subNode;
                } else {
                   childMap = new HashMap<String, MountNode>(childMap);
-                  subNode = new MountNode();
+                  subNode = new MountNode(mountNode);
                   childMap.put(seg, subNode);
                   mountNode.nodeMap = childMap;
                   mountNode = subNode;
@@ -334,12 +334,52 @@
 
       public void close() throws IOException
       {
-         final MountNode mountNode = this.mountNode;
-         synchronized (mountNode) {
-            if (mountNode.mount == this) {
-               mountNode.mount = null;
-               log.debugf("Unmounted %s for %s on %s", this, fileSystem, this);
-               
+         unmountFrom(rootMountNode, realMountPoint.iterator());
+      }
+
+      private boolean unmountFrom(MountNode node, Iterator<String> iter)
+      {
+         synchronized (node) {
+            final Map<String, MountNode> nodeMap = node.nodeMap;
+            if (iter.hasNext()) {
+               if (nodeMap != null) {
+                  final String key = iter.next();
+                  final MountNode nextNode = nodeMap.get(key);
+                  if (nextNode == null) {
+                     return nodeMap.isEmpty();
+                  }
+                  final boolean emptySubNode = unmountFrom(nextNode, iter);
+                  if (emptySubNode) {
+                     final boolean otherChildren = nodeMap.size() > 1;
+                     // subnode is dead; remove it from our map
+                     if (otherChildren) {
+                        // there's other children; not dead yet
+                        final HashMap<String, MountNode> newMap = new HashMap<String, MountNode>(nodeMap);
+                        newMap.remove(key);
+                        node.nodeMap = newMap;
+                        return false;
+                     } else {
+                        // no other children; dead if there's no mount here
+                        node.nodeMap = null;
+                        return node.mount == null;
+                     }
+                  }
+                  // subnode isn't empty; not dead
+                  return false;
+               } else {
+                  // dead node if there's no mount here
+                  return node.mount == null;
+               }
+            } else {
+               if (node.mount == this) {
+                  node.mount = null;
+                  log.debugf("Unmounted %s for %s on %s", this, fileSystem, this);
+                  // the node is dead if there are no children
+                  return nodeMap == null;
+               } else {
+                  // Node must be already unmounted; do cleanup work anyway.
+                  return node.mount == null && nodeMap == null;
+               }
             }
          }
       }
@@ -360,6 +400,7 @@
     */
    private static final class MountNode {
 
+      private final MountNode parent;
       /**
        * The immutable node map.  Since the map is immutable, changes to this field must be accomplished by replacing
        * the field value with a new map (copy on write).  Modifications to this field are protected by {@code this}.
@@ -369,5 +410,10 @@
        * The current mount at this point.  Modifications to this field are protected by {@code this}.
        */
       private volatile Mount mount;
+
+      private MountNode(MountNode parent)
+      {
+         this.parent = parent;
+      }
    }
 }




More information about the jboss-cvs-commits mailing list