Don't use own thread for drive syncing to disk, use Minecraft's background executor instead
This commit is contained in:
parent
8e03b4363d
commit
4430fdcb6b
@ -142,8 +142,6 @@ public final class OverdriveThatMatters {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setup(final FMLCommonSetupEvent event) {
|
private void setup(final FMLCommonSetupEvent event) {
|
||||||
EVENT_BUS.addListener(EventPriority.HIGHEST, DrivePool.INSTANCE::serverStopEvent);
|
|
||||||
EVENT_BUS.addListener(EventPriority.LOWEST, DrivePool.INSTANCE::serverStartEvent);
|
|
||||||
EVENT_BUS.addListener(EventPriority.NORMAL, DrivePool.INSTANCE::onWorldSave);
|
EVENT_BUS.addListener(EventPriority.NORMAL, DrivePool.INSTANCE::onWorldSave);
|
||||||
|
|
||||||
EVENT_BUS.addListener(EventPriority.HIGHEST, GlobalEventHandlerKt::onServerStopped);
|
EVENT_BUS.addListener(EventPriority.HIGHEST, GlobalEventHandlerKt::onServerStopped);
|
||||||
|
@ -6,6 +6,7 @@ import net.minecraft.ReportedException
|
|||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.nbt.NbtIo
|
import net.minecraft.nbt.NbtIo
|
||||||
import net.minecraft.CrashReport
|
import net.minecraft.CrashReport
|
||||||
|
import net.minecraft.Util
|
||||||
import net.minecraft.world.level.storage.LevelResource
|
import net.minecraft.world.level.storage.LevelResource
|
||||||
import java.util.concurrent.locks.LockSupport
|
import java.util.concurrent.locks.LockSupport
|
||||||
import net.minecraftforge.event.server.ServerAboutToStartEvent
|
import net.minecraftforge.event.server.ServerAboutToStartEvent
|
||||||
@ -14,6 +15,7 @@ import net.minecraftforge.event.level.LevelEvent
|
|||||||
import org.apache.logging.log4j.LogManager
|
import org.apache.logging.log4j.LogManager
|
||||||
import ru.dbotthepony.mc.otm.NULLABLE_MINECRAFT_SERVER
|
import ru.dbotthepony.mc.otm.NULLABLE_MINECRAFT_SERVER
|
||||||
import ru.dbotthepony.mc.otm.SERVER_IS_LIVE
|
import ru.dbotthepony.mc.otm.SERVER_IS_LIVE
|
||||||
|
import ru.dbotthepony.mc.otm.isServerThread
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
@ -61,14 +63,10 @@ object DrivePool {
|
|||||||
private val resource = LevelResource("otm_drives")
|
private val resource = LevelResource("otm_drives")
|
||||||
private val LOGGER = LogManager.getLogger()
|
private val LOGGER = LogManager.getLogger()
|
||||||
private val pool = Object2ObjectOpenHashMap<UUID, WeakDriveReference>()
|
private val pool = Object2ObjectOpenHashMap<UUID, WeakDriveReference>()
|
||||||
private var thread: Thread? = null
|
|
||||||
private var stopping = false
|
|
||||||
|
|
||||||
private val backlog = ConcurrentLinkedQueue<BacklogLine>()
|
private val backlog = ConcurrentLinkedQueue<BacklogLine>()
|
||||||
private var knownBaseDirectory: File? = null
|
private var knownBaseDirectory: File? = null
|
||||||
|
|
||||||
private var serverThread: Thread? = null
|
|
||||||
|
|
||||||
private val baseDirectory: File? get() {
|
private val baseDirectory: File? get() {
|
||||||
val server = NULLABLE_MINECRAFT_SERVER ?: return null
|
val server = NULLABLE_MINECRAFT_SERVER ?: return null
|
||||||
|
|
||||||
@ -83,7 +81,7 @@ object DrivePool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
operator fun <T : IMatteryDrive<*>> get(id: UUID, deserializer: (CompoundTag) -> T, factory: () -> T): T {
|
operator fun <T : IMatteryDrive<*>> get(id: UUID, deserializer: (CompoundTag) -> T, factory: () -> T): T {
|
||||||
if (!isLegalAccess())
|
if (!isServerThread())
|
||||||
throw IllegalAccessException("Can not access drive pool from outside of server thread.")
|
throw IllegalAccessException("Can not access drive pool from outside of server thread.")
|
||||||
|
|
||||||
if (!SERVER_IS_LIVE)
|
if (!SERVER_IS_LIVE)
|
||||||
@ -115,47 +113,11 @@ object DrivePool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun markDirty(id: UUID) {
|
fun markDirty(id: UUID) {
|
||||||
if (isLegalAccess()) {
|
if (isServerThread()) {
|
||||||
pool[id]?.access()
|
pool[id]?.access()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whenever running on server thread. Calling [get], [put] or [markDirty] will throw an exception if this returns false.
|
|
||||||
*
|
|
||||||
* If you are making your own drive for your own storage stack, feed code outside of server thread (e.g. client code) dummy disk.
|
|
||||||
*/
|
|
||||||
fun isLegalAccess(): Boolean {
|
|
||||||
return serverThread != null && Thread.currentThread() === serverThread
|
|
||||||
}
|
|
||||||
|
|
||||||
fun serverStartEvent(event: ServerAboutToStartEvent) {
|
|
||||||
if (thread?.isAlive == true) {
|
|
||||||
LOGGER.error("FMLServerStartedEvent fired twice.")
|
|
||||||
LOGGER.error("Attempting to start another DrivePool I/O thread when already running one!")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
pool.clear()
|
|
||||||
serverThread = Thread.currentThread()
|
|
||||||
|
|
||||||
stopping = false
|
|
||||||
thread = Thread(null, this::run, "Overdrive That Matters DrivePool IO").also { it.start() }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun serverStopEvent(event: ServerStoppingEvent) {
|
|
||||||
val thread = thread
|
|
||||||
|
|
||||||
if (thread != null && thread.isAlive) {
|
|
||||||
stopping = true
|
|
||||||
LockSupport.unpark(thread)
|
|
||||||
}
|
|
||||||
|
|
||||||
writeBacklog()
|
|
||||||
sync()
|
|
||||||
pool.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onWorldSave(event: LevelEvent.Save) {
|
fun onWorldSave(event: LevelEvent.Save) {
|
||||||
writeBacklog()
|
writeBacklog()
|
||||||
}
|
}
|
||||||
@ -185,14 +147,7 @@ object DrivePool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (needsSync) {
|
if (needsSync) {
|
||||||
LockSupport.unpark(thread)
|
Util.backgroundExecutor().execute(::sync)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun run() {
|
|
||||||
while (!stopping) {
|
|
||||||
sync()
|
|
||||||
LockSupport.park()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package ru.dbotthepony.mc.otm.item
|
package ru.dbotthepony.mc.otm.item
|
||||||
|
|
||||||
import ru.dbotthepony.mc.otm.capability.drive.DrivePool.isLegalAccess
|
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraftforge.common.capabilities.ICapabilityProvider
|
import net.minecraftforge.common.capabilities.ICapabilityProvider
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
@ -24,6 +23,7 @@ import ru.dbotthepony.mc.otm.container.ItemFilter
|
|||||||
import ru.dbotthepony.mc.otm.core.nbt.map
|
import ru.dbotthepony.mc.otm.core.nbt.map
|
||||||
import ru.dbotthepony.mc.otm.core.nbt.set
|
import ru.dbotthepony.mc.otm.core.nbt.set
|
||||||
import ru.dbotthepony.mc.otm.core.tagNotNull
|
import ru.dbotthepony.mc.otm.core.tagNotNull
|
||||||
|
import ru.dbotthepony.mc.otm.isServerThread
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ class PortableCondensationDriveItem(capacity: Int) :
|
|||||||
private var uuid: UUID? = null
|
private var uuid: UUID? = null
|
||||||
|
|
||||||
private val resolver = LazyOptional.of<IMatteryDrive<*>> {
|
private val resolver = LazyOptional.of<IMatteryDrive<*>> {
|
||||||
if (!isLegalAccess()) {
|
if (!isServerThread()) {
|
||||||
return@of ItemMatteryDrive.DUMMY
|
return@of ItemMatteryDrive.DUMMY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user