diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheTest.java index 8f30fd082..a1cec2d91 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheTest.java @@ -194,4 +194,18 @@ public class RepositoryCacheTest extends RepositoryTestCase { db.close(); assertEquals(0, ((Repository) db).useCnt.get()); } + + public void testRepositoryUnregisteringWhenClosing() throws Exception { + FileKey loc = FileKey.exact(db.getDirectory(), db.getFS()); + Repository d2 = RepositoryCache.open(loc); + assertEquals(1, d2.useCnt.get()); + assertThat(RepositoryCache.getRegisteredKeys(), + hasItem(FileKey.exact(db.getDirectory(), db.getFS()))); + assertEquals(1, RepositoryCache.getRegisteredKeys().size()); + + d2.close(); + + assertEquals(0, d2.useCnt.get()); + assertEquals(0, RepositoryCache.getRegisteredKeys().size()); + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java index 5546b790e..ba0dea39f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java @@ -865,6 +865,7 @@ public abstract class Repository implements AutoCloseable { public void close() { if (useCnt.decrementAndGet() == 0) { doClose(); + RepositoryCache.unregister(this); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java index 58771857b..22b5fcd11 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java @@ -130,10 +130,10 @@ public class RepositoryCache { } /** - * Remove a repository from the cache. + * Close and remove a repository from the cache. *

- * Removes a repository from the cache, if it is still registered here, - * permitting it to close. + * Removes a repository from the cache, if it is still registered here, and + * close it. * * @param db * repository to unregister. @@ -141,15 +141,35 @@ public class RepositoryCache { public static void close(final Repository db) { if (db.getDirectory() != null) { FileKey key = FileKey.exact(db.getDirectory(), db.getFS()); - cache.unregisterRepository(key); + cache.unregisterAndCloseRepository(key); } } /** * Remove a repository from the cache. *

- * Removes a repository from the cache, if it is still registered here, - * permitting it to close. + * Removes a repository from the cache, if it is still registered here. This + * method will not close the repository, only remove it from the cache. See + * {@link RepositoryCache#close(Repository)} to remove and close the + * repository. + * + * @param db + * repository to unregister. + * @since 4.3 + */ + public static void unregister(final Repository db) { + if (db.getDirectory() != null) { + unregister(FileKey.exact(db.getDirectory(), db.getFS())); + } + } + + /** + * Remove a repository from the cache. + *

+ * Removes a repository from the cache, if it is still registered here. This + * method will not close the repository, only remove it from the cache. See + * {@link RepositoryCache#close(Repository)} to remove and close the + * repository. * * @param location * location of the repository to remove. @@ -214,11 +234,16 @@ public class RepositoryCache { oldDb.close(); } - private void unregisterRepository(final Key location) { + private Repository unregisterRepository(final Key location) { Reference oldRef = cacheMap.remove(location); - Repository oldDb = oldRef != null ? oldRef.get() : null; - if (oldDb != null) + return oldRef != null ? oldRef.get() : null; + } + + private void unregisterAndCloseRepository(final Key location) { + Repository oldDb = unregisterRepository(location); + if (oldDb != null) { oldDb.close(); + } } private Collection getKeys() {