diff options
author | rickyes <mail@zhoumq.cn> | 2020-04-28 21:00:35 +0300 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2020-05-09 08:59:08 +0300 |
commit | be7fd2d517abd852d9ee3cf099fb007370af1910 (patch) | |
tree | e8cbf46afa10ac149155622d69df9e9953197632 /lib/internal/fs | |
parent | 28e6626ce7020b490438e3ee8a8188a59c5f856f (diff) |
fs: add .ref() and .unref() methods to watcher classes
PR-URL: https://github.com/nodejs/node/pull/33134
Fixes: https://github.com/nodejs/node/issues/33096
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Diffstat (limited to 'lib/internal/fs')
-rw-r--r-- | lib/internal/fs/watchers.js | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/lib/internal/fs/watchers.js b/lib/internal/fs/watchers.js index 118f85d9ada..01db66c551c 100644 --- a/lib/internal/fs/watchers.js +++ b/lib/internal/fs/watchers.js @@ -31,6 +31,9 @@ const kUseBigint = Symbol('kUseBigint'); const kFSWatchStart = Symbol('kFSWatchStart'); const kFSStatWatcherStart = Symbol('kFSStatWatcherStart'); +const KFSStatWatcherRefCount = Symbol('KFSStatWatcherRefCount'); +const KFSStatWatcherMaxRefCount = Symbol('KFSStatWatcherMaxRefCount'); +const kFSStatWatcherAddOrCleanRef = Symbol('kFSStatWatcherAddOrCleanRef'); function emitStop(self) { self.emit('stop'); @@ -42,6 +45,8 @@ function StatWatcher(bigint) { this._handle = null; this[kOldStatus] = -1; this[kUseBigint] = bigint; + this[KFSStatWatcherRefCount] = 1; + this[KFSStatWatcherMaxRefCount] = 1; } ObjectSetPrototypeOf(StatWatcher.prototype, EventEmitter.prototype); ObjectSetPrototypeOf(StatWatcher, EventEmitter); @@ -75,7 +80,7 @@ StatWatcher.prototype[kFSStatWatcherStart] = function(filename, this._handle[owner_symbol] = this; this._handle.onchange = onchange; if (!persistent) - this._handle.unref(); + this.unref(); // uv_fs_poll is a little more powerful than ev_stat but we curb it for // the sake of backwards compatibility. @@ -117,6 +122,41 @@ StatWatcher.prototype.stop = function() { this._handle = null; }; +// Clean up or add ref counters. +StatWatcher.prototype[kFSStatWatcherAddOrCleanRef] = function(operate) { + if (operate === 'add') { + // Add a Ref + this[KFSStatWatcherRefCount]++; + this[KFSStatWatcherMaxRefCount]++; + } else if (operate === 'clean') { + // Clean up a single + this[KFSStatWatcherMaxRefCount]--; + this.unref(); + } else if (operate === 'cleanAll') { + // Clean up all + this[KFSStatWatcherMaxRefCount] = 0; + this[KFSStatWatcherRefCount] = 0; + this._handle && this._handle.unref(); + } +}; + +StatWatcher.prototype.ref = function() { + // Avoid refCount calling ref multiple times causing unref to have no effect. + if (this[KFSStatWatcherRefCount] === this[KFSStatWatcherMaxRefCount]) + return this; + if (this._handle && this[KFSStatWatcherRefCount]++ === 0) + this._handle.ref(); + return this; +}; + +StatWatcher.prototype.unref = function() { + // Avoid refCount calling unref multiple times causing ref to have no effect. + if (this[KFSStatWatcherRefCount] === 0) return this; + if (this._handle && --this[KFSStatWatcherRefCount] === 0) + this._handle.unref(); + return this; +}; + function FSWatcher() { EventEmitter.call(this); @@ -208,6 +248,16 @@ FSWatcher.prototype.close = function() { process.nextTick(emitCloseNT, this); }; +FSWatcher.prototype.ref = function() { + if (this._handle) this._handle.ref(); + return this; +}; + +FSWatcher.prototype.unref = function() { + if (this._handle) this._handle.unref(); + return this; +}; + function emitCloseNT(self) { self.emit('close'); } @@ -223,5 +273,6 @@ module.exports = { FSWatcher, StatWatcher, kFSWatchStart, - kFSStatWatcherStart + kFSStatWatcherStart, + kFSStatWatcherAddOrCleanRef, }; |