mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-22 23:53:48 +01:00
Merge pull request #2152 from MartinFournier/fix/kill-rendering-process
Crash render process when javascript won't execute
This commit is contained in:
commit
0bddb7d349
30
electron/exit.html
Normal file
30
electron/exit.html
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<title>Bitburner</title>
|
||||||
|
<link rel="stylesheet" href="main.css" />
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: black;
|
||||||
|
color: #0c0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<h1>Exiting ...</h1>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -68,10 +68,17 @@ function createWindow(killall) {
|
|||||||
// here. Hey if it works it works.
|
// here. Hey if it works it works.
|
||||||
const achievements = greenworks.getAchievementNames();
|
const achievements = greenworks.getAchievementNames();
|
||||||
const intervalID = setInterval(async () => {
|
const intervalID = setInterval(async () => {
|
||||||
const achs = await win.webContents.executeJavaScript("document.achievements");
|
try {
|
||||||
for (const ach of achs) {
|
const achs = await win.webContents.executeJavaScript("document.achievements");
|
||||||
if (!achievements.includes(ach)) continue;
|
for (const ach of achs) {
|
||||||
greenworks.activateAchievement(ach, () => undefined);
|
if (!achievements.includes(ach)) continue;
|
||||||
|
greenworks.activateAchievement(ach, () => undefined);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// The interval properly did not properly get cleared after a window kill
|
||||||
|
log.warn('Clearing achievements timer');
|
||||||
|
clearInterval(intervalID);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
win.achievementsIntervalID = intervalID;
|
win.achievementsIntervalID = intervalID;
|
||||||
@ -81,8 +88,13 @@ function createWindow(killall) {
|
|||||||
setStopProcessHandler(app, win, false);
|
setStopProcessHandler(app, win, false);
|
||||||
if (intervalID) clearInterval(intervalID);
|
if (intervalID) clearInterval(intervalID);
|
||||||
win.webContents.forcefullyCrashRenderer();
|
win.webContents.forcefullyCrashRenderer();
|
||||||
|
win.on('closed', () => {
|
||||||
|
// Wait for window to be closed before opening the new one to prevent race conditions
|
||||||
|
log.debug('Opening new window');
|
||||||
|
const newWindow = createWindow(killScripts);
|
||||||
|
setStopProcessHandler(app, newWindow, true);
|
||||||
|
})
|
||||||
win.close();
|
win.close();
|
||||||
createWindow(killScripts);
|
|
||||||
};
|
};
|
||||||
const promptForReload = () => {
|
const promptForReload = () => {
|
||||||
win.off('unresponsive', promptForReload);
|
win.off('unresponsive', promptForReload);
|
||||||
@ -170,10 +182,39 @@ function createWindow(killall) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setStopProcessHandler(app, window, enabled) {
|
function setStopProcessHandler(app, window, enabled) {
|
||||||
const clearWindowHandler = () => {
|
const closingWindowHandler = async (e) => {
|
||||||
|
// We need to prevent the default closing event to add custom logic
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// First we clear the achievement timer
|
||||||
if (window.achievementsIntervalID) {
|
if (window.achievementsIntervalID) {
|
||||||
clearInterval(window.achievementsIntervalID);
|
clearInterval(window.achievementsIntervalID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We'll try to execute javascript on the page to see if we're stuck
|
||||||
|
let canRunJS = false;
|
||||||
|
win.webContents.executeJavaScript('window.stop(); document.close()', true)
|
||||||
|
.then(() => canRunJS = true);
|
||||||
|
setTimeout(() => {
|
||||||
|
// Wait a few milliseconds to prevent a race condition before loading the exit screen
|
||||||
|
win.webContents.stop();
|
||||||
|
win.loadFile("exit.html")
|
||||||
|
}, 20);
|
||||||
|
|
||||||
|
// Wait 200ms, if the promise has not yet resolved, let's crash the process since we're possibly in a stuck scenario
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!canRunJS) {
|
||||||
|
// We're stuck, let's crash the process
|
||||||
|
log.warn('Forcefully crashing the renderer process');
|
||||||
|
win.webContents.forcefullyCrashRenderer();
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug('Destroying the window');
|
||||||
|
win.destroy();
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
const clearWindowHandler = () => {
|
||||||
window = null;
|
window = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -181,15 +222,18 @@ function setStopProcessHandler(app, window, enabled) {
|
|||||||
log.info('Quitting the app...');
|
log.info('Quitting the app...');
|
||||||
app.isQuiting = true;
|
app.isQuiting = true;
|
||||||
app.quit();
|
app.quit();
|
||||||
// eslint-disable-next-line no-process-exit
|
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
|
log.debug('Adding closing handlers');
|
||||||
window.on("closed", clearWindowHandler);
|
window.on("closed", clearWindowHandler);
|
||||||
|
window.on("close", closingWindowHandler)
|
||||||
app.on("window-all-closed", stopProcessHandler);
|
app.on("window-all-closed", stopProcessHandler);
|
||||||
} else {
|
} else {
|
||||||
|
log.debug('Removing closing handlers');
|
||||||
window.removeListener("closed", clearWindowHandler);
|
window.removeListener("closed", clearWindowHandler);
|
||||||
|
window.removeListener("close", closingWindowHandler);
|
||||||
app.removeListener("window-all-closed", stopProcessHandler);
|
app.removeListener("window-all-closed", stopProcessHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user