Skip to content
This repository was archived by the owner on Apr 22, 2023. It is now read-only.
This repository was archived by the owner on Apr 22, 2023. It is now read-only.

setTimeout can’t work well after the process is blocked #15447

Closed
@ilc-opensource

Description

@ilc-opensource

node.js version: 4d9c81b (latest version), v0.10.33, node-v0.12.2
Platform: Ubuntu 14.04.1 LTS
Architecture: x86_64

var block = require('bindings')('hello'); // c++ addon
var a = function() {
  var timer = (new Date()).getTime();
  console.log('before block:'+timer);

  block.hello(); // will be block at some time

  timer = (new Date()).getTime();
  console.log('after block:'+timer);

  setTimeout(a, 5000);
};
a();

In the above script, function a will be executed very 5000 milliseconds if the block.hello is not blocked; But if the block.hello is blocked in c++ code, the time point which function a will be executed again is much larger than 5000 milliseconds after block.hello is unblocked. The following is the output of the above script:
1 before block:1429079335210
2 after block:1429079335210
3 before block:1429079340215
4 after block:1429079366741
5 before block:1429079398298
6 after block:1429079398299
7 before block:1429079403304
8 after block:1429079403304
Time interval between line2 and line 3 is 5005;
Time interval between line4 and line 5 is 31557;
Time interval between line6 and line 7 is 5005;

block.hello is blocked and unblocked between line 3 and line 4.

How to reproduce the issue?

  1. Download the tar file and decompress; https://www.dropbox.com/s/1y299n1y1uy69ij/node_js_debug.tar?dl=0
  2. cd node_js_debug;
  3. sh build.sh;
  4. node a.js;
  5. In another terminal, ./setFrontEndApp 123456; after a while, ./setFrontEndApp 0

How to fix?

I find we should recalculate now each time when processing the pending time events.

diff --git a/lib/timers.js b/lib/timers.js
index 68f87d7..c6af7f9 100644
--- a/lib/timers.js
+++ b/lib/timers.js
@@ -80,11 +80,10 @@ function listOnTimeout() {

   debug('timeout callback %d', msecs);

-  var now = Timer.now();
-  debug('now: %s', now);
-
   var diff, first, threw;
   while (first = L.peek(list)) {
+    var now = Timer.now();
+    debug('now: %s', now);
     diff = now - first._idleStart;
     if (diff < msecs) {
       list.start(msecs - diff, 0);

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions