Prevent rare shutdown exception

This commit is contained in:
Michael Primm 2022-12-11 21:10:52 -06:00
parent fe100abb51
commit 9f9d12a580
1 changed files with 20 additions and 16 deletions

View File

@ -18,6 +18,7 @@ public class GenericChunkCache {
}; };
private CacheHashMap snapcache; private CacheHashMap snapcache;
private final Object snapcachelock;
private ReferenceQueue<ChunkCacheRec> refqueue; private ReferenceQueue<ChunkCacheRec> refqueue;
private long cache_attempts; private long cache_attempts;
private long cache_success; private long cache_success;
@ -50,6 +51,7 @@ public class GenericChunkCache {
* Create snapshot cache * Create snapshot cache
*/ */
public GenericChunkCache(int max_size, boolean softref) { public GenericChunkCache(int max_size, boolean softref) {
snapcachelock = new Object();
snapcache = new CacheHashMap(max_size); snapcache = new CacheHashMap(max_size);
refqueue = new ReferenceQueue<ChunkCacheRec>(); refqueue = new ReferenceQueue<ChunkCacheRec>();
this.softref = softref; this.softref = softref;
@ -62,8 +64,8 @@ public class GenericChunkCache {
*/ */
public void invalidateSnapshot(String w, int x, int y, int z) { public void invalidateSnapshot(String w, int x, int y, int z) {
String key = getKey(w, x>>4, z>>4); String key = getKey(w, x>>4, z>>4);
synchronized(snapcache) { synchronized(snapcachelock) {
CacheRec rec = snapcache.remove(key); CacheRec rec = (snapcache != null) ? snapcache.remove(key) : null;
if(rec != null) { if(rec != null) {
snapcache.reverselookup.remove(rec.ref); snapcache.reverselookup.remove(rec.ref);
rec.ref.clear(); rec.ref.clear();
@ -78,8 +80,8 @@ public class GenericChunkCache {
for(int xx = (x0>>4); xx <= (x1>>4); xx++) { for(int xx = (x0>>4); xx <= (x1>>4); xx++) {
for(int zz = (z0>>4); zz <= (z1>>4); zz++) { for(int zz = (z0>>4); zz <= (z1>>4); zz++) {
String key = getKey(w, xx, zz); String key = getKey(w, xx, zz);
synchronized(snapcache) { synchronized(snapcachelock) {
CacheRec rec = snapcache.remove(key); CacheRec rec = (snapcache != null) ? snapcache.remove(key) : null;
if(rec != null) { if(rec != null) {
snapcache.reverselookup.remove(rec.ref); snapcache.reverselookup.remove(rec.ref);
rec.ref.clear(); rec.ref.clear();
@ -97,8 +99,8 @@ public class GenericChunkCache {
processRefQueue(); processRefQueue();
ChunkCacheRec ss = null; ChunkCacheRec ss = null;
CacheRec rec; CacheRec rec;
synchronized(snapcache) { synchronized(snapcachelock) {
rec = snapcache.get(key); rec = (snapcache != null) ? snapcache.get(key) : null;
if(rec != null) { if(rec != null) {
ss = rec.ref.get(); ss = rec.ref.get();
if(ss == null) { if(ss == null) {
@ -123,8 +125,8 @@ public class GenericChunkCache {
rec.ref = new SoftReference<ChunkCacheRec>(ss, refqueue); rec.ref = new SoftReference<ChunkCacheRec>(ss, refqueue);
else else
rec.ref = new WeakReference<ChunkCacheRec>(ss, refqueue); rec.ref = new WeakReference<ChunkCacheRec>(ss, refqueue);
synchronized(snapcache) { synchronized(snapcachelock) {
CacheRec prevrec = snapcache.put(key, rec); CacheRec prevrec = (snapcache != null) ? snapcache.put(key, rec) : null;
if(prevrec != null) { if(prevrec != null) {
snapcache.reverselookup.remove(prevrec.ref); snapcache.reverselookup.remove(prevrec.ref);
} }
@ -137,8 +139,8 @@ public class GenericChunkCache {
private void processRefQueue() { private void processRefQueue() {
Reference<? extends ChunkCacheRec> ref; Reference<? extends ChunkCacheRec> ref;
while((ref = refqueue.poll()) != null) { while((ref = refqueue.poll()) != null) {
synchronized(snapcache) { synchronized(snapcachelock) {
String k = snapcache.reverselookup.remove(ref); String k = (snapcache != null) ? snapcache.reverselookup.remove(ref) : null;
if(k != null) { if(k != null) {
snapcache.remove(k); snapcache.remove(k);
} }
@ -164,11 +166,13 @@ public class GenericChunkCache {
* Cleanup * Cleanup
*/ */
public void cleanup() { public void cleanup() {
if(snapcache != null) { synchronized(snapcachelock) {
snapcache.clear(); if(snapcache != null) {
snapcache.reverselookup.clear(); snapcache.clear();
snapcache.reverselookup = null; snapcache.reverselookup.clear();
snapcache = null; snapcache.reverselookup = null;
} snapcache = null;
}
}
} }
} }