Clearing subscriptions during shutdown is now within a synchronized

block
This commit is contained in:
nathan 2016-04-03 17:34:37 +02:00
parent 3caa2fa2d2
commit 11891f0525
2 changed files with 20 additions and 12 deletions

View File

@ -66,7 +66,10 @@ class Subscription<T> {
this.entries = new IdentityMap<Object, Entry>(32, SubscriptionManager.LOAD_FACTOR);
}
// called on shutdown for GC purposes
/**
* called on shutdown for GC purposes
* called within SYNCHRONIZE
*/
public final
void clear() {
this.entries.clear();

View File

@ -17,11 +17,11 @@ package dorkbox.messagebus.subscription;
import com.esotericsoftware.kryo.util.IdentityMap;
import dorkbox.messagebus.MessageBus;
import dorkbox.messagebus.common.MultiClass;
import dorkbox.messagebus.subscription.reflection.ReflectionFactory;
import dorkbox.messagebus.common.ClassTree;
import dorkbox.messagebus.common.MessageHandler;
import dorkbox.messagebus.common.MultiClass;
import dorkbox.messagebus.subscription.asm.AsmFactory;
import dorkbox.messagebus.subscription.reflection.ReflectionFactory;
import dorkbox.messagebus.util.ClassUtils;
import java.util.ArrayList;
@ -134,6 +134,10 @@ class SubscriptionManager {
public
void shutdown() {
// synchronized is used here to ensure the "single writer principle", and make sure that ONLY one thread at a time can enter this
// section. Because of this, we can have unlimited reader threads all going at the same time, without contention (which is our
// use-case 99% of the time)
synchronized (singleWriterLock) {
// explicitly clear out the subscriptions
final IdentityMap.Entries<Class<?>, Subscription[]> entries = subsPerListener.entries();
for (IdentityMap.Entry<Class<?>, Subscription[]> entry : entries) {
@ -147,6 +151,7 @@ class SubscriptionManager {
}
}
}
}
this.nonListeners.clear();