diff options
author | Robin Rosenberg <robin.rosenberg@dewire.com> | 2011-11-10 02:07:04 -0500 |
---|---|---|
committer | Code Review <codereview-daemon@eclipse.org> | 2011-11-10 02:07:04 -0500 |
commit | c0392381ee915c8ddd08a5fe8b94548fd86b8fcd (patch) | |
tree | 38ed893060a873f3a98a9b62be5cdeaf9eb27540 /org.eclipse.jgit | |
parent | 45c714456b1e92a7a60794ba5aface025243ad82 (diff) | |
parent | 9652f16a474371a387b125de600483735690f6b9 (diff) | |
download | jgit-c0392381ee915c8ddd08a5fe8b94548fd86b8fcd.tar.gz jgit-c0392381ee915c8ddd08a5fe8b94548fd86b8fcd.zip |
Merge changes Ibb3467f7,I2af99903
* changes:
Always use try/finally around DfsBlockCache.clockLock
DfsBlockCache: Fix NPE when evicting empty cell
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsBlockCache.java | 78 |
1 files changed, 42 insertions, 36 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsBlockCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsBlockCache.java index d3dadbe295..ba704e5104 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsBlockCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsBlockCache.java @@ -206,7 +206,7 @@ public final class DfsBlockCache { blockSizeShift = Integer.numberOfTrailingZeros(blockSize); clockLock = new ReentrantLock(true /* fair */); - clockHand = new Ref<Object>(null, -1, 0, null); + clockHand = new Ref<Object>(new DfsPackKey(), -1, 0, null); clockHand.next = clockHand; readAheadLimit = cfg.getReadAheadLimit(); @@ -389,36 +389,39 @@ public final class DfsBlockCache { @SuppressWarnings("unchecked") private void reserveSpace(int reserve) { clockLock.lock(); - long live = liveBytes + reserve; - if (maxBytes < live) { - Ref prev = clockHand; - Ref hand = clockHand.next; - do { - if (hand.hot) { - // Value was recently touched. Clear - // hot and give it another chance. - hand.hot = false; - prev = hand; + try { + long live = liveBytes + reserve; + if (maxBytes < live) { + Ref prev = clockHand; + Ref hand = clockHand.next; + do { + if (hand.hot) { + // Value was recently touched. Clear + // hot and give it another chance. + hand.hot = false; + prev = hand; + hand = hand.next; + continue; + } else if (prev == hand) + break; + + // No recent access since last scan, kill + // value and remove from clock. + Ref dead = hand; hand = hand.next; - continue; - } else if (prev == hand) - break; - - // No recent access since last scan, kill - // value and remove from clock. - Ref dead = hand; - hand = hand.next; - prev.next = hand; - dead.next = null; - dead.value = null; - live -= dead.size; - dead.pack.cachedSize.addAndGet(-dead.size); - statEvict++; - } while (maxBytes < live); - clockHand = prev; + prev.next = hand; + dead.next = null; + dead.value = null; + live -= dead.size; + dead.pack.cachedSize.addAndGet(-dead.size); + statEvict++; + } while (maxBytes < live); + clockHand = prev; + } + liveBytes = live; + } finally { + clockLock.unlock(); } - liveBytes = live; - clockLock.unlock(); } private void creditSpace(int credit) { @@ -429,13 +432,16 @@ public final class DfsBlockCache { private void addToClock(Ref ref, int credit) { clockLock.lock(); - if (credit != 0) - liveBytes -= credit; - Ref ptr = clockHand; - ref.next = ptr.next; - ptr.next = ref; - clockHand = ref; - clockLock.unlock(); + try { + if (credit != 0) + liveBytes -= credit; + Ref ptr = clockHand; + ref.next = ptr.next; + ptr.next = ref; + clockHand = ref; + } finally { + clockLock.unlock(); + } } void put(DfsBlock v) { |