package org.torch.server; import com.destroystokyo.paper.PaperConfig; import com.google.common.collect.Queues; import lombok.Getter; import net.minecraft.server.*; import java.util.concurrent.LinkedBlockingQueue; import org.torch.api.TorchReactor; @Getter public final class TorchIOThread implements Runnable, TorchReactor { /** The chunks need to save. */ private final LinkedBlockingQueue<IAsyncChunkSaver> chunkSaverQueue = Queues.newLinkedBlockingQueue(); private static final class LazyInstance { private static TorchIOThread instance = new TorchIOThread(); } private TorchIOThread() { Thread thread = new Thread(this, "File IO Thread"); thread.setPriority(1); thread.start(); } /** * Retrieves an instance of the TorchIOThread */ public static TorchIOThread getInstance() { return TorchIOThread.LazyInstance.instance; } @Override public void run() { this.processQueuedChunks(); } /** * Process the items that are in the queue */ public void processQueuedChunks() { try { while (true) this.tryWriteChunk(chunkSaverQueue.take()); } catch (Throwable t) { t.printStackTrace(); TorchServer.getServer().safeShutdown(); } } /** * Process a chunk, re-add to the queue if unsuccessful */ private void tryWriteChunk(IAsyncChunkSaver chunkSaver) throws InterruptedException { if (!chunkSaver.c()) { // PAIL: WriteNextIO() -> Returns if the write was unsuccessful this.getServant().incrementSavedChunkCounter(); // Port if (PaperConfig.enableFileIOThreadSleep) Thread.sleep(this.getServant().isWaitingFinish() ? 0L : 2L); // Paper - Add toggle } else { chunkSaverQueue.add(chunkSaver); } } public void queueChunkToSaving(IAsyncChunkSaver chunkSsaver) { if (!this.chunkSaverQueue.contains(chunkSsaver)) { this.chunkSaverQueue.add(chunkSsaver); this.getServant().incrementWriteQueuedCounter(); // Port } } public void waitForFinish() throws InterruptedException { this.getServant().toggleWaitingFinish(); while (!chunkSaverQueue.isEmpty()) { this.tryWriteChunk(chunkSaverQueue.take()); } this.getServant().toggleWaitingFinish(); } @Override public FileIOThread getServant() { return FileIOThread.a(); } }