Always use try/finally around DfsBlockCache.clockLock
Any RuntimeException or Error in this block will leave the lock held by the caller thread, which can later result in deadlock or just cache requests hanging forever because they cannot get to the lock object. Wrap everything in try/finally to prevent the lock from hanging, even though a RuntimeException or Error should never happen in any of these code paths. Change-Id: Ibb3467f7ee4c06f617b737858b4be17b10d936e0
This commit is contained in:
parent
a6677ef28a
commit
9652f16a47
|
@ -389,6 +389,7 @@ DfsBlock getOrLoad(DfsPackFile pack, long position, DfsReader ctx)
|
|||
@SuppressWarnings("unchecked")
|
||||
private void reserveSpace(int reserve) {
|
||||
clockLock.lock();
|
||||
try {
|
||||
long live = liveBytes + reserve;
|
||||
if (maxBytes < live) {
|
||||
Ref prev = clockHand;
|
||||
|
@ -418,8 +419,10 @@ private void reserveSpace(int reserve) {
|
|||
clockHand = prev;
|
||||
}
|
||||
liveBytes = live;
|
||||
} finally {
|
||||
clockLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void creditSpace(int credit) {
|
||||
clockLock.lock();
|
||||
|
@ -429,14 +432,17 @@ private void creditSpace(int credit) {
|
|||
|
||||
private void addToClock(Ref ref, int credit) {
|
||||
clockLock.lock();
|
||||
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) {
|
||||
put(v.pack, v.start, v.size(), v);
|
||||
|
|
Loading…
Reference in New Issue