fix: libuv hang on Windows (#28175)
This commit is contained in:
parent
d10398610b
commit
665ac6f9c8
7 changed files with 86 additions and 6 deletions
|
@ -534,15 +534,13 @@ void NodeBindings::LoadEnvironment(node::Environment* env) {
|
||||||
void NodeBindings::PrepareMessageLoop() {
|
void NodeBindings::PrepareMessageLoop() {
|
||||||
#if !defined(OS_WIN)
|
#if !defined(OS_WIN)
|
||||||
int handle = uv_backend_fd(uv_loop_);
|
int handle = uv_backend_fd(uv_loop_);
|
||||||
#else
|
|
||||||
HANDLE handle = uv_loop_->iocp;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// If the backend fd hasn't changed, don't proceed.
|
// If the backend fd hasn't changed, don't proceed.
|
||||||
if (handle == handle_)
|
if (handle == handle_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
handle_ = handle;
|
handle_ = handle;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Add dummy handle for libuv, otherwise libuv would quit when there is
|
// Add dummy handle for libuv, otherwise libuv would quit when there is
|
||||||
// nothing to do.
|
// nothing to do.
|
||||||
|
|
|
@ -159,9 +159,7 @@ class NodeBindings {
|
||||||
// Isolate data used in creating the environment
|
// Isolate data used in creating the environment
|
||||||
node::IsolateData* isolate_data_ = nullptr;
|
node::IsolateData* isolate_data_ = nullptr;
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if !defined(OS_WIN)
|
||||||
HANDLE handle_;
|
|
||||||
#else
|
|
||||||
int handle_ = -1;
|
int handle_ = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
13
spec-main/fixtures/apps/libuv-hang/index.html
Normal file
13
spec-main/fixtures/apps/libuv-hang/index.html
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
|
||||||
|
<meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'">
|
||||||
|
<title>Hello World!</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Hello World!</h1>
|
||||||
|
<script src="./renderer.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
36
spec-main/fixtures/apps/libuv-hang/main.js
Normal file
36
spec-main/fixtures/apps/libuv-hang/main.js
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
const { app, BrowserWindow, ipcMain } = require('electron');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
async function createWindow () {
|
||||||
|
const mainWindow = new BrowserWindow({
|
||||||
|
show: false,
|
||||||
|
webPreferences: {
|
||||||
|
preload: path.join(__dirname, 'preload.js')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await mainWindow.loadFile('index.html');
|
||||||
|
}
|
||||||
|
|
||||||
|
app.whenReady().then(() => {
|
||||||
|
createWindow();
|
||||||
|
app.on('activate', function () {
|
||||||
|
if (BrowserWindow.getAllWindows().length === 0) {
|
||||||
|
createWindow();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
let count = 0;
|
||||||
|
ipcMain.handle('reload-successful', () => {
|
||||||
|
if (count === 2) {
|
||||||
|
app.quit();
|
||||||
|
} else {
|
||||||
|
count++;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.on('window-all-closed', function () {
|
||||||
|
if (process.platform !== 'darwin') app.quit();
|
||||||
|
});
|
16
spec-main/fixtures/apps/libuv-hang/preload.js
Normal file
16
spec-main/fixtures/apps/libuv-hang/preload.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
const { contextBridge, ipcRenderer } = require('electron');
|
||||||
|
|
||||||
|
contextBridge.exposeInMainWorld('api', {
|
||||||
|
ipcRenderer,
|
||||||
|
run: async () => {
|
||||||
|
const { promises: fs } = require('fs');
|
||||||
|
for (let i = 0; i < 10; i++) {
|
||||||
|
const list = await fs.readdir('.', { withFileTypes: true });
|
||||||
|
for (const file of list) {
|
||||||
|
if (file.isFile()) {
|
||||||
|
await fs.readFile(file.name, 'utf-8');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
8
spec-main/fixtures/apps/libuv-hang/renderer.js
Normal file
8
spec-main/fixtures/apps/libuv-hang/renderer.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
const count = localStorage.getItem('count');
|
||||||
|
|
||||||
|
const { run, ipcRenderer } = window.api;
|
||||||
|
|
||||||
|
run().then(async () => {
|
||||||
|
const count = await ipcRenderer.invoke('reload-successful');
|
||||||
|
if (count < 3) location.reload();
|
||||||
|
}).catch(console.log);
|
|
@ -7,6 +7,7 @@ import { ifdescribe, ifit } from './spec-helpers';
|
||||||
import { webContents, WebContents } from 'electron/main';
|
import { webContents, WebContents } from 'electron/main';
|
||||||
|
|
||||||
const features = process._linkedBinding('electron_common_features');
|
const features = process._linkedBinding('electron_common_features');
|
||||||
|
const mainFixturesPath = path.resolve(__dirname, 'fixtures');
|
||||||
|
|
||||||
describe('node feature', () => {
|
describe('node feature', () => {
|
||||||
const fixtures = path.join(__dirname, '..', 'spec', 'fixtures');
|
const fixtures = path.join(__dirname, '..', 'spec', 'fixtures');
|
||||||
|
@ -22,6 +23,16 @@ describe('node feature', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not hang when using the fs module in the renderer process', async () => {
|
||||||
|
const appPath = path.join(mainFixturesPath, 'apps', 'libuv-hang', 'main.js');
|
||||||
|
const appProcess = childProcess.spawn(process.execPath, [appPath], {
|
||||||
|
cwd: path.join(mainFixturesPath, 'apps', 'libuv-hang'),
|
||||||
|
stdio: 'inherit'
|
||||||
|
});
|
||||||
|
const [code] = await emittedOnce(appProcess, 'close');
|
||||||
|
expect(code).to.equal(0);
|
||||||
|
});
|
||||||
|
|
||||||
describe('contexts', () => {
|
describe('contexts', () => {
|
||||||
describe('setTimeout called under Chromium event loop in browser process', () => {
|
describe('setTimeout called under Chromium event loop in browser process', () => {
|
||||||
it('Can be scheduled in time', (done) => {
|
it('Can be scheduled in time', (done) => {
|
||||||
|
|
Loading…
Reference in a new issue