summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorDave Borowitz2011-11-10 15:58:13 (EST)
committer Dave Borowitz2011-11-14 13:27:45 (EST)
commit2b584b92165f8dc711a2a4dfb00d49af8fe84a3a (patch)
treebe237e1712e50e81a93f281545a084e2f704d5a3
parentf26b79d04453b64ab9eead7130b099c7c90fd9ab (diff)
downloadjgit-2b584b92165f8dc711a2a4dfb00d49af8fe84a3a.zip
jgit-2b584b92165f8dc711a2a4dfb00d49af8fe84a3a.tar.gz
jgit-2b584b92165f8dc711a2a4dfb00d49af8fe84a3a.tar.bz2
Keep track of a static collection of all PackWriter instancesrefs/changes/95/4595/2
Stored in a weak concurrent hash map, which we clean up while iterating. Usually the weak reference behavior should not be necessary because PackWriters should be released with release(), but we still want to avoid leaks when dealing with broken client code. Change-Id: I337abb952ac6524f7f920fedf04065edf84d01d2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java52
1 files changed, 52 insertions, 0 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java
index aac288e..95fc7a9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java
@@ -49,6 +49,7 @@ import static org.eclipse.jgit.storage.pack.StoredObjectRepresentation.PACK_WHOL
import java.io.IOException;
import java.io.OutputStream;
+import java.lang.ref.WeakReference;
import java.security.MessageDigest;
import java.text.MessageFormat;
import java.util.ArrayList;
@@ -62,7 +63,9 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
@@ -141,6 +144,50 @@ import org.eclipse.jgit.util.TemporaryBuffer;
public class PackWriter {
private static final int PACK_VERSION_GENERATED = 2;
+ private static final Map<WeakReference<PackWriter>, Boolean> instances =
+ new ConcurrentHashMap<WeakReference<PackWriter>, Boolean>();
+
+ private static final Iterable<PackWriter> instancesIterable = new Iterable<PackWriter>() {
+ public Iterator<PackWriter> iterator() {
+ return new Iterator<PackWriter>() {
+ private final Iterator<WeakReference<PackWriter>> it =
+ instances.keySet().iterator();
+ private PackWriter next;
+
+ public boolean hasNext() {
+ if (next != null)
+ return true;
+ while (it.hasNext()) {
+ WeakReference<PackWriter> ref = it.next();
+ next = ref.get();
+ if (next != null)
+ return true;
+ it.remove();
+ }
+ return false;
+ }
+
+ public PackWriter next() {
+ if (hasNext()) {
+ PackWriter result = next;
+ next = null;
+ return result;
+ }
+ throw new NoSuchElementException();
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+ };
+
+ /** @return all allocated, non-released PackWriters instances. */
+ public static Iterable<PackWriter> getInstances() {
+ return instancesIterable;
+ }
+
@SuppressWarnings("unchecked")
private final BlockList<ObjectToPack> objectsLists[] = new BlockList[Constants.OBJ_TAG + 1];
{
@@ -176,6 +223,8 @@ public class PackWriter {
private final MutableState state;
+ private final WeakReference<PackWriter> selfRef;
+
private Statistics.ObjectType typeStats;
private List<ObjectToPack> sortedByName;
@@ -269,6 +318,8 @@ public class PackWriter {
reuseValidate = true; // be paranoid by default
stats = new Statistics();
state = new MutableState();
+ selfRef = new WeakReference<PackWriter>(this);
+ instances.put(selfRef, Boolean.TRUE);
}
/**
@@ -901,6 +952,7 @@ public class PackWriter {
myDeflater.end();
myDeflater = null;
}
+ instances.remove(selfRef);
}
private void searchForReuse(ProgressMonitor monitor) throws IOException {