You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by th...@apache.org on 2009/05/27 12:21:11 UTC

svn commit: r779084 - /jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/GarbageCollector.java

Author: thomasm
Date: Wed May 27 10:21:11 2009
New Revision: 779084

URL: http://svn.apache.org/viewvc?rev=779084&view=rev
Log:
JCR-2106 SystemSessions created for GarbageCollector are not logged out

Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/GarbageCollector.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/GarbageCollector.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/GarbageCollector.java?rev=779084&r1=779083&r2=779084&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/GarbageCollector.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/GarbageCollector.java Wed May 27 10:21:11 2009
@@ -34,6 +34,7 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import javax.jcr.Item;
 import javax.jcr.Node;
@@ -84,6 +85,9 @@
     private final IterablePersistenceManager[] pmList;
 
     private final Session[] sessionList;
+    private final SessionListener sessionListener;
+    
+    private final AtomicBoolean closed = new AtomicBoolean();
 
     private boolean persistenceManagerScan;
 
@@ -94,25 +98,26 @@
      * This method is usually not called by the application, it is called
      * by SessionImpl.createDataStoreGarbageCollector().
      *
+     * @param session the session that created this object
      * @param list the persistence managers
+     * @param sessionList the sessions to access the workspaces
      */
-    public GarbageCollector(final SessionImpl session, IterablePersistenceManager[] list, final Session[] sessionList) {
+    public GarbageCollector(SessionImpl session, IterablePersistenceManager[] list, Session[] sessionList) {
         RepositoryImpl rep = (RepositoryImpl) session.getRepository();
         store = rep.getDataStore();
         this.pmList = list;
         this.persistenceManagerScan = list != null;
         this.sessionList = sessionList;
         
-        // log out each session as soon as the main session logs out
-        session.addListener(new SessionListener() {
+        // Auto-close if the main session logs out
+        this.sessionListener = new SessionListener() {
             public void loggedOut(SessionImpl session) {
-                for (Session s: sessionList) {
-                    s.logout();
-                }
             }
             public void loggingOut(SessionImpl session) {
+                close();
             }
-        });
+        };
+        session.addListener(sessionListener);
     }
 
     /**
@@ -241,6 +246,10 @@
         }
     }
 
+    /**
+     * The repository was scanned. This method will stop the observation
+     * listener.
+     */
     public void stopScan() throws RepositoryException {
         checkScanStarted();
         for (Listener listener : listeners) {
@@ -253,6 +262,11 @@
         listeners.clear();
     }
 
+    /**
+     * Delete all unused items in the data store.
+     * 
+     * @return the number of deleted items
+     */
     public int deleteUnused() throws RepositoryException {
         checkScanStarted();
         checkScanStopped();
@@ -271,6 +285,11 @@
         }
     }
 
+    /**
+     * Get the data store if one is used.
+     * 
+     * @return the data store, or null
+     */
     public DataStore getDataStore() {
         return store;
     }
@@ -339,9 +358,31 @@
          *
          * We can't use node path for this, UUIDs are required as nodes could be
          * moved around.
+         * 
+         * This mechanism requires that all data stores update the last modified 
+         * date when calling addRecord and that record already exists.
          *
          */
     }
+    
+    /**
+     * Cleanup resources used internally by this instance.
+     */
+    public void close() {
+        if (!closed.getAndSet(true)) {
+            for (Session s : sessionList) {
+                s.logout();
+            }
+        }
+    }
+
+    /**
+     * Auto-close in case the application didn't call it explicitly.
+     */
+    protected void finalize() throws Throwable {
+        close();
+        super.finalize();
+    }
 
     /**
      * Event listener to detect moved nodes.