Browse Source

fix: override the timers module impls to activate the uv loop (#18961)

trop[bot] 5 years ago
parent
commit
212c6b1266
2 changed files with 57 additions and 8 deletions
  1. 13 8
      lib/common/init.ts
  2. 44 0
      spec/node-spec.js

+ 13 - 8
lib/common/init.ts

@@ -1,8 +1,9 @@
-import * as timers from 'timers'
 import * as util from 'util'
 
 import { electronBindingSetup } from '@electron/internal/common/atom-binding-setup'
 
+const timers = require('timers')
+
 process.electronBinding = electronBindingSetup(process._linkedBinding, process.type)
 
 type AnyFn = (...args: any[]) => any
@@ -38,16 +39,20 @@ function wrap <T extends AnyFn> (func: T, wrapper: (fn: AnyFn) => T) {
 
 process.nextTick = wrapWithActivateUvLoop(process.nextTick)
 
-global.setImmediate = wrapWithActivateUvLoop(timers.setImmediate)
+global.setImmediate = timers.setImmediate = wrapWithActivateUvLoop(timers.setImmediate)
 global.clearImmediate = timers.clearImmediate
 
+// setTimeout needs to update the polling timeout of the event loop, when
+// called under Chromium's event loop the node's event loop won't get a chance
+// to update the timeout, so we have to force the node's event loop to
+// recalculate the timeout in browser process.
+timers.setTimeout = wrapWithActivateUvLoop(timers.setTimeout)
+timers.setInterval = wrapWithActivateUvLoop(timers.setInterval)
+
+// Only override the global setTimeout/setInterval impls in the browser process
 if (process.type === 'browser') {
-  // setTimeout needs to update the polling timeout of the event loop, when
-  // called under Chromium's event loop the node's event loop won't get a chance
-  // to update the timeout, so we have to force the node's event loop to
-  // recalculate the timeout in browser process.
-  global.setTimeout = wrapWithActivateUvLoop(timers.setTimeout)
-  global.setInterval = wrapWithActivateUvLoop(timers.setInterval)
+  global.setTimeout = timers.setTimeout
+  global.setInterval = timers.setInterval
 }
 
 if (process.platform === 'win32') {

+ 44 - 0
spec/node-spec.js

@@ -212,6 +212,16 @@ describe('node feature', () => {
       })
     })
 
+    describe('setTimeout called under blink env in renderer process', () => {
+      it('can be scheduled in time', (done) => {
+        setTimeout(done, 10)
+      })
+
+      it('works from the timers module', (done) => {
+        require('timers').setTimeout(done, 10)
+      })
+    })
+
     describe('setInterval called under Chromium event loop in browser process', () => {
       it('can be scheduled in time', (done) => {
         let interval = null
@@ -229,6 +239,40 @@ describe('node feature', () => {
         interval = remote.getGlobal('setInterval')(clear, 10)
       })
     })
+
+    describe('setInterval called under blink env in renderer process', () => {
+      it('can be scheduled in time', (done) => {
+        let interval = null
+        let clearing = false
+        const clear = () => {
+          if (interval === null || clearing) return
+
+          // interval might trigger while clearing (remote is slow sometimes)
+          clearing = true
+          clearInterval(interval)
+          clearing = false
+          interval = null
+          done()
+        }
+        interval = setInterval(clear, 10)
+      })
+
+      it('can be scheduled in time from timers module', (done) => {
+        let interval = null
+        let clearing = false
+        const clear = () => {
+          if (interval === null || clearing) return
+
+          // interval might trigger while clearing (remote is slow sometimes)
+          clearing = true
+          require('timers').clearInterval(interval)
+          clearing = false
+          interval = null
+          done()
+        }
+        interval = require('timers').setInterval(clear, 10)
+      })
+    })
   })
 
   describe('inspector', () => {