2025-11-24 22:52:51 +03:00

94 lines
3.3 KiB
Java

/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* com.mojang.logging.LogUtils
* org.jspecify.annotations.Nullable
* org.slf4j.Logger
*/
package net.minecraft.util;
import com.mojang.logging.LogUtils;
import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import net.minecraft.CrashReport;
import net.minecraft.CrashReportCategory;
import net.minecraft.ReportedException;
import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
public class ThreadingDetector {
private static final Logger LOGGER = LogUtils.getLogger();
private final String name;
private final Semaphore lock = new Semaphore(1);
private final Lock stackTraceLock = new ReentrantLock();
private volatile @Nullable Thread threadThatFailedToAcquire;
private volatile @Nullable ReportedException fullException;
public ThreadingDetector(String name) {
this.name = name;
}
public void checkAndLock() {
block6: {
boolean released = false;
try {
this.stackTraceLock.lock();
if (this.lock.tryAcquire()) break block6;
this.threadThatFailedToAcquire = Thread.currentThread();
released = true;
this.stackTraceLock.unlock();
try {
this.lock.acquire();
}
catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
}
throw this.fullException;
}
finally {
if (!released) {
this.stackTraceLock.unlock();
}
}
}
}
public void checkAndUnlock() {
try {
this.stackTraceLock.lock();
Thread threadThatFailedToAcquire = this.threadThatFailedToAcquire;
if (threadThatFailedToAcquire != null) {
ReportedException fullException;
this.fullException = fullException = ThreadingDetector.makeThreadingException(this.name, threadThatFailedToAcquire);
this.lock.release();
throw fullException;
}
this.lock.release();
}
finally {
this.stackTraceLock.unlock();
}
}
public static ReportedException makeThreadingException(String name, @Nullable Thread threadThatFailedToAcquire) {
String threads = Stream.of(Thread.currentThread(), threadThatFailedToAcquire).filter(Objects::nonNull).map(ThreadingDetector::stackTrace).collect(Collectors.joining("\n"));
String error = "Accessing " + name + " from multiple threads";
CrashReport report = new CrashReport(error, new IllegalStateException(error));
CrashReportCategory category = report.addCategory("Thread dumps");
category.setDetail("Thread dumps", threads);
LOGGER.error("Thread dumps: \n{}", (Object)threads);
return new ReportedException(report);
}
private static String stackTrace(Thread thread) {
return thread.getName() + ": \n\tat " + Arrays.stream(thread.getStackTrace()).map(Object::toString).collect(Collectors.joining("\n\tat "));
}
}