mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-08-04 03:46:57 -04:00
Merge 449a6f1386002a38c34422098002e950928f706a into 9969dc60c5278340b6b9a4d7facdde620e99d1f5
This commit is contained in:
commit
33b54b39bb
@ -25,6 +25,7 @@ import org.jackhuang.hmcl.util.Log4jLevel;
|
|||||||
import org.jackhuang.hmcl.util.StringUtils;
|
import org.jackhuang.hmcl.util.StringUtils;
|
||||||
import org.jackhuang.hmcl.util.platform.ManagedProcess;
|
import org.jackhuang.hmcl.util.platform.ManagedProcess;
|
||||||
import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
||||||
|
import org.jackhuang.hmcl.util.platform.SystemUtils;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -54,7 +55,7 @@ final class ExitWaiter implements Runnable {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
int exitCode = process.getProcess().waitFor();
|
int exitCode = SystemUtils.waitFor(process.getProcess());
|
||||||
|
|
||||||
for (Thread thread : joins)
|
for (Thread thread : joins)
|
||||||
thread.join();
|
thread.join();
|
||||||
|
@ -205,7 +205,7 @@ public enum Architecture {
|
|||||||
if (CURRENT_ARCH == X86_64) {
|
if (CURRENT_ARCH == X86_64) {
|
||||||
try {
|
try {
|
||||||
Process process = Runtime.getRuntime().exec(new String[]{"/usr/sbin/sysctl", "-n", "sysctl.proc_translated"});
|
Process process = Runtime.getRuntime().exec(new String[]{"/usr/sbin/sysctl", "-n", "sysctl.proc_translated"});
|
||||||
if (process.waitFor(3, TimeUnit.SECONDS) && process.exitValue() == 0
|
if (SystemUtils.waitFor(process, 3, TimeUnit.SECONDS) && process.exitValue() == 0
|
||||||
&& "1".equals(IOUtils.readFullyAsString(process.getInputStream(), OperatingSystem.NATIVE_CHARSET).trim())) {
|
&& "1".equals(IOUtils.readFullyAsString(process.getInputStream(), OperatingSystem.NATIVE_CHARSET).trim())) {
|
||||||
sysArch = ARM64;
|
sysArch = ARM64;
|
||||||
}
|
}
|
||||||
@ -221,7 +221,7 @@ public enum Architecture {
|
|||||||
if (new File(uname).exists()) {
|
if (new File(uname).exists()) {
|
||||||
try {
|
try {
|
||||||
Process process = Runtime.getRuntime().exec(new String[]{uname, "-m"});
|
Process process = Runtime.getRuntime().exec(new String[]{uname, "-m"});
|
||||||
if (process.waitFor(3, TimeUnit.SECONDS) && process.exitValue() == 0) {
|
if (SystemUtils.waitFor(process, 3, TimeUnit.SECONDS) && process.exitValue() == 0) {
|
||||||
sysArch = parseArchName(IOUtils.readFullyAsString(process.getInputStream(), OperatingSystem.NATIVE_CHARSET).trim());
|
sysArch = parseArchName(IOUtils.readFullyAsString(process.getInputStream(), OperatingSystem.NATIVE_CHARSET).trim());
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
@ -72,7 +72,7 @@ public final class SystemUtils {
|
|||||||
ManagedProcess managedProcess = new ManagedProcess(processBuilder);
|
ManagedProcess managedProcess = new ManagedProcess(processBuilder);
|
||||||
managedProcess.pumpInputStream(SystemUtils::onLogLine);
|
managedProcess.pumpInputStream(SystemUtils::onLogLine);
|
||||||
managedProcess.pumpErrorStream(SystemUtils::onLogLine);
|
managedProcess.pumpErrorStream(SystemUtils::onLogLine);
|
||||||
return managedProcess.getProcess().waitFor();
|
return waitFor(managedProcess.getProcess());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String run(String... command) throws Exception {
|
public static String run(String... command) throws Exception {
|
||||||
@ -95,7 +95,7 @@ public final class SystemUtils {
|
|||||||
Lang.wrap(() -> convert.apply(inputStream)),
|
Lang.wrap(() -> convert.apply(inputStream)),
|
||||||
Schedulers.io());
|
Schedulers.io());
|
||||||
|
|
||||||
if (!process.waitFor(15, TimeUnit.SECONDS))
|
if (!SystemUtils.waitFor(process, 15, TimeUnit.SECONDS))
|
||||||
throw new TimeoutException();
|
throw new TimeoutException();
|
||||||
|
|
||||||
if (process.exitValue() != 0)
|
if (process.exitValue() != 0)
|
||||||
@ -115,4 +115,58 @@ public final class SystemUtils {
|
|||||||
private static void onLogLine(String log) {
|
private static void onLogLine(String log) {
|
||||||
LOG.info(log);
|
LOG.info(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>A low performance implementation of {@link Process#waitFor()}</p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* On Windows, JVM invoke
|
||||||
|
* <a href="https://github.com/openjdk/jdk/blob/b77bd5fd6a6f7ddbed90300fba790da4fb683275/src/java.base/windows/native/libjava/ProcessImpl_md.c#L428-L459">WaitForMultipleObjects</a>
|
||||||
|
* to wait the specific process and VM thread interrupt flag at the same time.
|
||||||
|
* However, this API might throw unexpected exception, causing a IOException on Java level.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The following codes replace native implementation with software ones.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public static int waitFor(Process process) throws InterruptedException {
|
||||||
|
if (OperatingSystem.CURRENT_OS != OperatingSystem.WINDOWS) {
|
||||||
|
return process.waitFor();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
return process.exitValue();
|
||||||
|
} catch (IllegalThreadStateException e2) {
|
||||||
|
// noinspection BusyWait
|
||||||
|
Thread.sleep(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See {@link #waitFor(Process)}
|
||||||
|
*/
|
||||||
|
public static boolean waitFor(Process process, long timeout, TimeUnit unit) throws InterruptedException {
|
||||||
|
if (OperatingSystem.CURRENT_OS != OperatingSystem.WINDOWS) {
|
||||||
|
return process.waitFor(timeout, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
long startTime = System.nanoTime();
|
||||||
|
long rem = unit.toNanos(timeout);
|
||||||
|
|
||||||
|
do {
|
||||||
|
try {
|
||||||
|
process.exitValue();
|
||||||
|
return true;
|
||||||
|
} catch (IllegalThreadStateException ex) {
|
||||||
|
if (rem > 0)
|
||||||
|
Thread.sleep(
|
||||||
|
Math.min(TimeUnit.NANOSECONDS.toMillis(rem) + 1, 100));
|
||||||
|
}
|
||||||
|
rem = unit.toNanos(timeout) - (System.nanoTime() - startTime);
|
||||||
|
} while (rem > 0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user