aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.test/tst/org/eclipse
diff options
context:
space:
mode:
authorKevin Sawicki <kevin@github.com>2012-05-10 19:13:24 -0700
committerKevin Sawicki <kevin@github.com>2012-05-28 14:06:12 -0700
commit91f5ce3a15d5df61de42fbe72a368ac513081d5b (patch)
tree2561f87cf3cbaebfdb54b925851e61c1556b0941 /org.eclipse.jgit.test/tst/org/eclipse
parent24a0f47e32ab7cdf20c2201d7100599ea057f8a3 (diff)
downloadjgit-91f5ce3a15d5df61de42fbe72a368ac513081d5b.tar.gz
jgit-91f5ce3a15d5df61de42fbe72a368ac513081d5b.zip
Only increment mod count if packed-refs file changes
Previously if a packed-refs file was racily clean then there was a 2.5 second window in which each call to getPackedRefs would increment the mod count causing a RefsChangedEvent to be fired since the FileSnapshot would report the file as modified. If a RefsChangedListener called getRef/getRefs from the onRefsChanged method then a StackOverflowError could occur since the stack could be exhausted before the 2.5 second window expired and the packed-refs file would no longer report being modified. Now a SHA-1 is computed of the packed-refs file and the mod count is only incremented when the packed refs are successfully set and the id of the new packed-refs file does not match the id of the old packed-refs file. Change-Id: I8cab6e5929479ed748812b8598c7628370e79697
Diffstat (limited to 'org.eclipse.jgit.test/tst/org/eclipse')
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/RefDirectoryTest.java32
1 files changed, 32 insertions, 0 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/RefDirectoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/RefDirectoryTest.java
index 3ca4f589db..508b690509 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/RefDirectoryTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/RefDirectoryTest.java
@@ -60,6 +60,8 @@ import static org.junit.Assert.fail;
import java.io.File;
import java.io.IOException;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jgit.events.ListenerHandle;
import org.eclipse.jgit.events.RefsChangedEvent;
@@ -1077,6 +1079,36 @@ public class RefDirectoryTest extends LocalDiskRepositoryTestCase {
assertSame(master_p2, refdir.peel(master_p2));
}
+ @Test
+ public void testRefsChangedStackOverflow() throws Exception {
+ final FileRepository newRepo = createBareRepository();
+ final RefDatabase refDb = newRepo.getRefDatabase();
+ File packedRefs = new File(newRepo.getDirectory(), "packed-refs");
+ assertTrue(packedRefs.createNewFile());
+ final AtomicReference<StackOverflowError> error = new AtomicReference<StackOverflowError>();
+ final AtomicReference<IOException> exception = new AtomicReference<IOException>();
+ final AtomicInteger changeCount = new AtomicInteger();
+ newRepo.getListenerList().addRefsChangedListener(
+ new RefsChangedListener() {
+
+ public void onRefsChanged(RefsChangedEvent event) {
+ try {
+ refDb.getRefs("ref");
+ changeCount.incrementAndGet();
+ } catch (StackOverflowError soe) {
+ error.set(soe);
+ } catch (IOException ioe) {
+ exception.set(ioe);
+ }
+ }
+ });
+ refDb.getRefs("ref");
+ refDb.getRefs("ref");
+ assertNull(error.get());
+ assertNull(exception.get());
+ assertEquals(1, changeCount.get());
+ }
+
private void writeLooseRef(String name, AnyObjectId id) throws IOException {
writeLooseRef(name, id.name() + "\n");
}