Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 522e3d3

Browse filesBrowse files
indutnyrvagg
authored andcommitted
timers: reuse timer in setTimeout().unref()
Instead of creating new timer - reuse the timer from the freelist. This won't make the freelist timer active for the duration of `uv_close()`, and will let the event-loop exit properly. Fix: #1264 PR-URL: #3407 Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
1 parent b483afc commit 522e3d3
Copy full SHA for 522e3d3

File tree

Expand file treeCollapse file tree

2 files changed

+42
-7
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

2 files changed

+42
-7
lines changed
Open diff view settings
Collapse file

‎lib/timers.js‎

Copy file name to clipboardExpand all lines: lib/timers.js
+22-7Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -119,16 +119,27 @@ function listOnTimeoutNT(list) {
119119
}
120120

121121

122-
const unenroll = exports.unenroll = function(item) {
122+
function reuse(item) {
123123
L.remove(item);
124124

125125
var list = lists[item._idleTimeout];
126-
// if empty then stop the watcher
127-
debug('unenroll');
126+
// if empty - reuse the watcher
128127
if (list && L.isEmpty(list)) {
128+
debug('reuse hit');
129+
list.stop();
130+
delete lists[item._idleTimeout];
131+
return list;
132+
}
133+
134+
return null;
135+
}
136+
137+
138+
const unenroll = exports.unenroll = function(item) {
139+
var list = reuse(item);
140+
if (list) {
129141
debug('unenroll: list empty');
130142
list.close();
131-
delete lists[item._idleTimeout];
132143
}
133144
// if active is called later, then we want to make sure not to insert again
134145
item._idleTimeout = -1;
@@ -312,12 +323,16 @@ Timeout.prototype.unref = function() {
312323
if (!this._idleStart) this._idleStart = now;
313324
var delay = this._idleStart + this._idleTimeout - now;
314325
if (delay < 0) delay = 0;
315-
exports.unenroll(this);
316326

317327
// Prevent running cb again when unref() is called during the same cb
318-
if (this._called && !this._repeat) return;
328+
if (this._called && !this._repeat) {
329+
exports.unenroll(this);
330+
return;
331+
}
332+
333+
var handle = reuse(this);
319334

320-
this._handle = new Timer();
335+
this._handle = handle || new Timer();
321336
this._handle.owner = this;
322337
this._handle[kOnTimeout] = unrefdHandle;
323338
this._handle.start(delay, 0);
Collapse file
+20Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
'use strict';
2+
3+
require('../common');
4+
const assert = require('assert');
5+
6+
var once = 0;
7+
8+
process.on('beforeExit', () => {
9+
if (once > 1)
10+
throw new RangeError('beforeExit should only have been called once!');
11+
12+
setTimeout(() => {}, 1).unref();
13+
once++;
14+
});
15+
16+
process.on('exit', (code) => {
17+
if (code !== 0) return;
18+
19+
assert.strictEqual(once, 1);
20+
});

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.