Synchronization

- Make PonderRegistry use a ThreadLocal current namespace
- Add synchronized blocks to some methods that modify maps or lists
- Move some non-thread safe method calls to the event.enqueueWork
lambdas
This commit is contained in:
PepperBell 2021-07-31 17:28:41 -07:00
parent 296b302160
commit 99be93e8a6
8 changed files with 68 additions and 41 deletions

View file

@ -109,6 +109,7 @@ public class Create {
modEventBus.addListener(AllConfigs::onReload); modEventBus.addListener(AllConfigs::onReload);
modEventBus.addListener(EventPriority.LOWEST, this::gatherData); modEventBus.addListener(EventPriority.LOWEST, this::gatherData);
forgeEventBus.addListener(EventPriority.HIGH, Create::onBiomeLoad); forgeEventBus.addListener(EventPriority.HIGH, Create::onBiomeLoad);
forgeEventBus.register(CHUNK_UTIL);
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, DistExecutor.unsafeRunWhenOn(Dist.CLIENT,
() -> () -> CreateClient.addClientListeners(forgeEventBus, modEventBus)); () -> () -> CreateClient.addClientListeners(forgeEventBus, modEventBus));
@ -116,16 +117,14 @@ public class Create {
public static void init(final FMLCommonSetupEvent event) { public static void init(final FMLCommonSetupEvent event) {
CapabilityMinecartController.register(); CapabilityMinecartController.register();
SchematicInstances.register();
CHUNK_UTIL.init();
MinecraftForge.EVENT_BUS.register(CHUNK_UTIL);
AllPackets.registerPackets(); AllPackets.registerPackets();
AllTriggers.register(); SchematicInstances.register();
PotatoCannonProjectileTypes.register(); PotatoCannonProjectileTypes.register();
CHUNK_UTIL.init();
event.enqueueWork(() -> { event.enqueueWork(() -> {
AllTriggers.register();
SchematicProcessor.register(); SchematicProcessor.register();
AllWorldFeatures.registerFeatures(); AllWorldFeatures.registerFeatures();
}); });

View file

@ -107,12 +107,12 @@ public class CreateClient {
UIRenderHelper.init(); UIRenderHelper.init();
IResourceManager resourceManager = Minecraft.getInstance()
.getResourceManager();
if (resourceManager instanceof IReloadableResourceManager)
((IReloadableResourceManager) resourceManager).registerReloadListener(new ResourceReloadHandler());
event.enqueueWork(() -> { event.enqueueWork(() -> {
IResourceManager resourceManager = Minecraft.getInstance()
.getResourceManager();
if (resourceManager instanceof IReloadableResourceManager)
((IReloadableResourceManager) resourceManager).registerReloadListener(new ResourceReloadHandler());
registerLayerRenderers(Minecraft.getInstance() registerLayerRenderers(Minecraft.getInstance()
.getEntityRenderDispatcher()); .getEntityRenderDispatcher());
}); });

View file

@ -253,11 +253,15 @@ public class PotatoCannonProjectileTypes {
; ;
public static void registerType(ResourceLocation resLoc, PotatoCannonProjectileTypes type) { public static void registerType(ResourceLocation resLoc, PotatoCannonProjectileTypes type) {
ALL.put(resLoc, type); synchronized (ALL) {
ALL.put(resLoc, type);
}
} }
public static void assignType(IRegistryDelegate<Item> item, PotatoCannonProjectileTypes type) { public static void assignType(IRegistryDelegate<Item> item, PotatoCannonProjectileTypes type) {
ITEM_MAP.put(item, type); synchronized (ITEM_MAP) {
ITEM_MAP.put(item, type);
}
} }
public static Optional<PotatoCannonProjectileTypes> getProjectileTypeOf(ItemStack item) { public static Optional<PotatoCannonProjectileTypes> getProjectileTypeOf(ItemStack item) {

View file

@ -41,23 +41,32 @@ public class PonderRegistry {
// Map from item ids to all storyboards // Map from item ids to all storyboards
public static final Map<ResourceLocation, List<PonderStoryBoardEntry>> ALL = new HashMap<>(); public static final Map<ResourceLocation, List<PonderStoryBoardEntry>> ALL = new HashMap<>();
private static String currentNamespace; private static final ThreadLocal<String> CURRENT_NAMESPACE = new ThreadLocal<>();
private static String getCurrentNamespace() {
return CURRENT_NAMESPACE.get();
}
private static void setCurrentNamespace(String namespace) {
CURRENT_NAMESPACE.set(namespace);
}
public static void startRegistration(String namespace) { public static void startRegistration(String namespace) {
if (currentNamespace != null) { if (getCurrentNamespace() != null) {
throw new IllegalStateException("Cannot start registration when already started!"); throw new IllegalStateException("Cannot start registration when already started!");
} }
currentNamespace = namespace; setCurrentNamespace(namespace);
} }
public static void endRegistration() { public static void endRegistration() {
if (currentNamespace == null) { if (getCurrentNamespace() == null) {
throw new IllegalStateException("Cannot end registration when not started!"); throw new IllegalStateException("Cannot end registration when not started!");
} }
currentNamespace = null; setCurrentNamespace(null);
} }
private static String getNamespaceOrThrow() { private static String getNamespaceOrThrow() {
String currentNamespace = getCurrentNamespace();
if (currentNamespace == null) { if (currentNamespace == null) {
throw new IllegalStateException("Cannot register storyboard without starting registration!"); throw new IllegalStateException("Cannot register storyboard without starting registration!");
} }
@ -71,8 +80,10 @@ public class PonderRegistry {
PonderSceneBuilder builder = new PonderSceneBuilder(entry); PonderSceneBuilder builder = new PonderSceneBuilder(entry);
if (tags.length > 0) if (tags.length > 0)
builder.highlightTags(tags); builder.highlightTags(tags);
ALL.computeIfAbsent(id, _$ -> new ArrayList<>()) synchronized (ALL) {
.add(entry); ALL.computeIfAbsent(id, _$ -> new ArrayList<>())
.add(entry);
}
return builder; return builder;
} }

View file

@ -22,11 +22,16 @@ public class PonderChapterRegistry {
} }
public void addStoriesToChapter(@Nonnull PonderChapter chapter, PonderStoryBoardEntry... entries) { public void addStoriesToChapter(@Nonnull PonderChapter chapter, PonderStoryBoardEntry... entries) {
chapters.get(chapter.getId()).getSecond().addAll(Arrays.asList(entries)); List<PonderStoryBoardEntry> entryList = chapters.get(chapter.getId()).getSecond();
synchronized (entryList) {
entryList.addAll(Arrays.asList(entries));
}
} }
PonderChapter addChapter(@Nonnull PonderChapter chapter) { PonderChapter addChapter(@Nonnull PonderChapter chapter) {
chapters.put(chapter.getId(), Pair.of(chapter, new ArrayList<>())); synchronized (chapters) {
chapters.put(chapter.getId(), Pair.of(chapter, new ArrayList<>()));
}
return chapter; return chapter;
} }

View file

@ -445,17 +445,17 @@ public class PonderIndex {
.add(Blocks.HONEY_BLOCK); .add(Blocks.HONEY_BLOCK);
PonderRegistry.TAGS.forTag(PonderTag.CONTRAPTION_ACTOR) PonderRegistry.TAGS.forTag(PonderTag.CONTRAPTION_ACTOR)
.add(AllBlocks.MECHANICAL_HARVESTER) .add(AllBlocks.MECHANICAL_HARVESTER)
.add(AllBlocks.MECHANICAL_PLOUGH) .add(AllBlocks.MECHANICAL_PLOUGH)
.add(AllBlocks.MECHANICAL_DRILL) .add(AllBlocks.MECHANICAL_DRILL)
.add(AllBlocks.MECHANICAL_SAW) .add(AllBlocks.MECHANICAL_SAW)
.add(AllBlocks.DEPLOYER) .add(AllBlocks.DEPLOYER)
.add(AllBlocks.PORTABLE_STORAGE_INTERFACE) .add(AllBlocks.PORTABLE_STORAGE_INTERFACE)
.add(AllBlocks.PORTABLE_FLUID_INTERFACE) .add(AllBlocks.PORTABLE_FLUID_INTERFACE)
.add(AllBlocks.MECHANICAL_BEARING) .add(AllBlocks.MECHANICAL_BEARING)
.add(AllBlocks.ANDESITE_FUNNEL) .add(AllBlocks.ANDESITE_FUNNEL)
.add(AllBlocks.BRASS_FUNNEL) .add(AllBlocks.BRASS_FUNNEL)
.add(AllBlocks.SEATS.get(DyeColor.WHITE)) .add(AllBlocks.SEATS.get(DyeColor.WHITE))
.add(AllBlocks.REDSTONE_CONTACT) .add(AllBlocks.REDSTONE_CONTACT)
.add(Blocks.BELL) .add(Blocks.BELL)
.add(Blocks.DISPENSER) .add(Blocks.DISPENSER)

View file

@ -49,11 +49,15 @@ public class PonderTagRegistry {
} }
public void add(PonderTag tag, ResourceLocation item) { public void add(PonderTag tag, ResourceLocation item) {
tags.put(item, tag); synchronized (tags) {
tags.put(item, tag);
}
} }
public void add(PonderTag tag, PonderChapter chapter) { public void add(PonderTag tag, PonderChapter chapter) {
chapterTags.put(chapter, tag); synchronized (chapterTags) {
chapterTags.put(chapter, tag);
}
} }
public ItemBuilder forItems(ResourceLocation... items) { public ItemBuilder forItems(ResourceLocation... items) {

View file

@ -28,7 +28,7 @@ import net.minecraft.util.math.BlockPos;
public class SuperByteBufferCache { public class SuperByteBufferCache {
Map<Compartment<?>, Cache<Object, SuperByteBuffer>> cache; private Map<Compartment<?>, Cache<Object, SuperByteBuffer>> cache;
public SuperByteBufferCache() { public SuperByteBufferCache() {
cache = new HashMap<>(); cache = new HashMap<>();
@ -87,14 +87,18 @@ public class SuperByteBufferCache {
} }
public void registerCompartment(Compartment<?> instance) { public void registerCompartment(Compartment<?> instance) {
cache.put(instance, CacheBuilder.newBuilder() synchronized (cache) {
.build()); cache.put(instance, CacheBuilder.newBuilder()
.build());
}
} }
public void registerCompartment(Compartment<?> instance, long ticksUntilExpired) { public void registerCompartment(Compartment<?> instance, long ticksUntilExpired) {
cache.put(instance, CacheBuilder.newBuilder() synchronized (cache) {
.expireAfterAccess(ticksUntilExpired * 50, TimeUnit.MILLISECONDS) cache.put(instance, CacheBuilder.newBuilder()
.build()); .expireAfterAccess(ticksUntilExpired * 50, TimeUnit.MILLISECONDS)
.build());
}
} }
private SuperByteBuffer standardBlockRender(BlockState renderedState) { private SuperByteBuffer standardBlockRender(BlockState renderedState) {