Skip to content

Commit 764be84

Browse files
fix: override the timers module impls to activate the uv loop (electron#18948)
1 parent fb01c94 commit 764be84

File tree

2 files changed

+57
-8
lines changed

2 files changed

+57
-8
lines changed

lib/common/init.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import * as timers from 'timers'
21
import * as util from 'util'
32

43
import { electronBindingSetup } from '@electron/internal/common/electron-binding-setup'
54

5+
const timers = require('timers')
6+
67
process.electronBinding = electronBindingSetup(process._linkedBinding, process.type)
78

89
type AnyFn = (...args: any[]) => any
@@ -38,16 +39,20 @@ function wrap <T extends AnyFn> (func: T, wrapper: (fn: AnyFn) => T) {
3839

3940
process.nextTick = wrapWithActivateUvLoop(process.nextTick)
4041

41-
global.setImmediate = wrapWithActivateUvLoop(timers.setImmediate)
42+
global.setImmediate = timers.setImmediate = wrapWithActivateUvLoop(timers.setImmediate)
4243
global.clearImmediate = timers.clearImmediate
4344

45+
// setTimeout needs to update the polling timeout of the event loop, when
46+
// called under Chromium's event loop the node's event loop won't get a chance
47+
// to update the timeout, so we have to force the node's event loop to
48+
// recalculate the timeout in browser process.
49+
timers.setTimeout = wrapWithActivateUvLoop(timers.setTimeout)
50+
timers.setInterval = wrapWithActivateUvLoop(timers.setInterval)
51+
52+
// Only override the global setTimeout/setInterval impls in the browser process
4453
if (process.type === 'browser') {
45-
// setTimeout needs to update the polling timeout of the event loop, when
46-
// called under Chromium's event loop the node's event loop won't get a chance
47-
// to update the timeout, so we have to force the node's event loop to
48-
// recalculate the timeout in browser process.
49-
global.setTimeout = wrapWithActivateUvLoop(timers.setTimeout)
50-
global.setInterval = wrapWithActivateUvLoop(timers.setInterval)
54+
global.setTimeout = timers.setTimeout
55+
global.setInterval = timers.setInterval
5156
}
5257

5358
if (process.platform === 'win32') {

spec/node-spec.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,16 @@ describe('node feature', () => {
212212
})
213213
})
214214

215+
describe('setTimeout called under blink env in renderer process', () => {
216+
it('can be scheduled in time', (done) => {
217+
setTimeout(done, 10)
218+
})
219+
220+
it('works from the timers module', (done) => {
221+
require('timers').setTimeout(done, 10)
222+
})
223+
})
224+
215225
describe('setInterval called under Chromium event loop in browser process', () => {
216226
it('can be scheduled in time', (done) => {
217227
let interval = null
@@ -229,6 +239,40 @@ describe('node feature', () => {
229239
interval = remote.getGlobal('setInterval')(clear, 10)
230240
})
231241
})
242+
243+
describe('setInterval called under blink env in renderer process', () => {
244+
it('can be scheduled in time', (done) => {
245+
let interval = null
246+
let clearing = false
247+
const clear = () => {
248+
if (interval === null || clearing) return
249+
250+
// interval might trigger while clearing (remote is slow sometimes)
251+
clearing = true
252+
clearInterval(interval)
253+
clearing = false
254+
interval = null
255+
done()
256+
}
257+
interval = setInterval(clear, 10)
258+
})
259+
260+
it('can be scheduled in time from timers module', (done) => {
261+
let interval = null
262+
let clearing = false
263+
const clear = () => {
264+
if (interval === null || clearing) return
265+
266+
// interval might trigger while clearing (remote is slow sometimes)
267+
clearing = true
268+
require('timers').clearInterval(interval)
269+
clearing = false
270+
interval = null
271+
done()
272+
}
273+
interval = require('timers').setInterval(clear, 10)
274+
})
275+
})
232276
})
233277

234278
describe('inspector', () => {

0 commit comments

Comments
 (0)