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) {
|
||||
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.HIGHEST, GlobalEventHandlerKt::onServerStopped);
|
||||
|
@ -6,6 +6,7 @@ import net.minecraft.ReportedException
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.NbtIo
|
||||
import net.minecraft.CrashReport
|
||||
import net.minecraft.Util
|
||||
import net.minecraft.world.level.storage.LevelResource
|
||||
import java.util.concurrent.locks.LockSupport
|
||||
import net.minecraftforge.event.server.ServerAboutToStartEvent
|
||||
@ -14,6 +15,7 @@ import net.minecraftforge.event.level.LevelEvent
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import ru.dbotthepony.mc.otm.NULLABLE_MINECRAFT_SERVER
|
||||
import ru.dbotthepony.mc.otm.SERVER_IS_LIVE
|
||||
import ru.dbotthepony.mc.otm.isServerThread
|
||||
import java.io.File
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.ArrayList
|
||||
@ -61,14 +63,10 @@ object DrivePool {
|
||||
private val resource = LevelResource("otm_drives")
|
||||
private val LOGGER = LogManager.getLogger()
|
||||
private val pool = Object2ObjectOpenHashMap<UUID, WeakDriveReference>()
|
||||
private var thread: Thread? = null
|
||||
private var stopping = false
|
||||
|
||||
private val backlog = ConcurrentLinkedQueue<BacklogLine>()
|
||||
private var knownBaseDirectory: File? = null
|
||||
|
||||
private var serverThread: Thread? = null
|
||||
|
||||
private val baseDirectory: File? get() {
|
||||
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 {
|
||||
if (!isLegalAccess())
|
||||
if (!isServerThread())
|
||||
throw IllegalAccessException("Can not access drive pool from outside of server thread.")
|
||||
|
||||
if (!SERVER_IS_LIVE)
|
||||
@ -115,47 +113,11 @@ object DrivePool {
|
||||
}
|
||||
|
||||
fun markDirty(id: UUID) {
|
||||
if (isLegalAccess()) {
|
||||
if (isServerThread()) {
|
||||
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) {
|
||||
writeBacklog()
|
||||
}
|
||||
@ -185,14 +147,7 @@ object DrivePool {
|
||||
}
|
||||
|
||||
if (needsSync) {
|
||||
LockSupport.unpark(thread)
|
||||
}
|
||||
}
|
||||
|
||||
private fun run() {
|
||||
while (!stopping) {
|
||||
sync()
|
||||
LockSupport.park()
|
||||
Util.backgroundExecutor().execute(::sync)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package ru.dbotthepony.mc.otm.item
|
||||
|
||||
import ru.dbotthepony.mc.otm.capability.drive.DrivePool.isLegalAccess
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraftforge.common.capabilities.ICapabilityProvider
|
||||
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.set
|
||||
import ru.dbotthepony.mc.otm.core.tagNotNull
|
||||
import ru.dbotthepony.mc.otm.isServerThread
|
||||
import java.math.BigInteger
|
||||
import java.util.*
|
||||
|
||||
@ -35,7 +35,7 @@ class PortableCondensationDriveItem(capacity: Int) :
|
||||
private var uuid: UUID? = null
|
||||
|
||||
private val resolver = LazyOptional.of<IMatteryDrive<*>> {
|
||||
if (!isLegalAccess()) {
|
||||
if (!isServerThread()) {
|
||||
return@of ItemMatteryDrive.DUMMY
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user