mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-14 01:04:24 +00:00
Fix potential issue with BackgroundScanHandler for users with slow disc IO (#8176)
This commit is contained in:
1 parent
ec7cb00f86
commit
a4e574fa6b
1 file changed
+24
-7
+24
-7
@@ -24,6 +24,8 @@ import net.minecraftforge.fml.loading.LoadingModList;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.*;
|
||||
@@ -32,12 +34,22 @@ import static net.minecraftforge.fml.loading.LogMarkers.SCAN;
|
||||
|
||||
public class BackgroundScanHandler
|
||||
{
|
||||
private enum ScanStatus {
|
||||
NOT_STARTED,
|
||||
RUNNING,
|
||||
COMPLETE,
|
||||
TIMED_OUT,
|
||||
INTERRUPTED,
|
||||
ERRORED
|
||||
}
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private final ExecutorService modContentScanner;
|
||||
private final List<ModFile> pendingFiles;
|
||||
private final List<ModFile> scannedFiles;
|
||||
private final List<ModFile> allFiles;
|
||||
private final List<ModFile> modFiles;
|
||||
private ScanStatus status;
|
||||
private LoadingModList loadingModList;
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
@@ -51,6 +63,7 @@ public class BackgroundScanHandler
|
||||
scannedFiles = new ArrayList<>();
|
||||
pendingFiles = new ArrayList<>();
|
||||
allFiles = new ArrayList<>();
|
||||
status = ScanStatus.NOT_STARTED;
|
||||
}
|
||||
|
||||
public List<ModFile> getModFiles() {
|
||||
@@ -59,8 +72,10 @@ public class BackgroundScanHandler
|
||||
|
||||
public void submitForScanning(final ModFile file) {
|
||||
if (modContentScanner.isShutdown()) {
|
||||
status = ScanStatus.ERRORED;
|
||||
throw new IllegalStateException("Scanner has shutdown");
|
||||
}
|
||||
status = ScanStatus.RUNNING;
|
||||
allFiles.add(file);
|
||||
pendingFiles.add(file);
|
||||
final CompletableFuture<ModFileScanData> future = CompletableFuture.supplyAsync(file::compileContent, modContentScanner)
|
||||
@@ -71,6 +86,7 @@ public class BackgroundScanHandler
|
||||
|
||||
private void addCompletedFile(final ModFile file, final ModFileScanData modFileScanData, final Throwable throwable) {
|
||||
if (throwable != null) {
|
||||
status = ScanStatus.ERRORED;
|
||||
LOGGER.error(SCAN,"An error occurred scanning file {}", file, throwable);
|
||||
}
|
||||
pendingFiles.remove(file);
|
||||
@@ -88,18 +104,19 @@ public class BackgroundScanHandler
|
||||
}
|
||||
|
||||
public void waitForScanToComplete(final Runnable ticker) {
|
||||
boolean interrupted = false;
|
||||
boolean succeeded = false;
|
||||
boolean timeoutActive = System.getProperty("fml.disableScanTimeout") == null;
|
||||
Instant deadline = Instant.now().plus(Duration.ofMinutes(10));
|
||||
modContentScanner.shutdown();
|
||||
do {
|
||||
ticker.run();
|
||||
try {
|
||||
succeeded = modContentScanner.awaitTermination(50, TimeUnit.MILLISECONDS);
|
||||
status = modContentScanner.awaitTermination(50, TimeUnit.MILLISECONDS) ? ScanStatus.COMPLETE : ScanStatus.RUNNING;
|
||||
} catch (InterruptedException e) {
|
||||
interrupted = true;
|
||||
status = ScanStatus.INTERRUPTED;
|
||||
}
|
||||
} while (!modContentScanner.isShutdown());
|
||||
if (interrupted) Thread.currentThread().interrupt();
|
||||
if (!succeeded) throw new IllegalStateException("Failed to complete mod scan");
|
||||
if (timeoutActive && Instant.now().isAfter(deadline)) status = ScanStatus.TIMED_OUT;
|
||||
} while (status == ScanStatus.RUNNING);
|
||||
if (status == ScanStatus.INTERRUPTED) Thread.currentThread().interrupt();
|
||||
if (status != ScanStatus.COMPLETE) throw new IllegalStateException("Failed to complete mod scan");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user