| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -579,6 +579,72 @@ added: v0.5.8 | |||
| 579 | 579 | Stop watching for changes on the given `fs.FSWatcher`. Once stopped, the | |
| 580 | 580 | `fs.FSWatcher` object is no longer usable. | |
| 581 | 581 | ||
| 582 | + ### `watcher.ref()` | ||
| 583 | + <!-- YAML | ||
| 584 | + added: REPLACEME | ||
| 585 | + --> | ||
| 586 | + | ||
| 587 | + * Returns: {fs.FSWatcher} | ||
| 588 | + | ||
| 589 | + When called, requests that the Node.js event loop *not* exit so long as the | ||
| 590 | + `FSWatcher` is active. Calling `watcher.ref()` multiple times will have | ||
| 591 | + no effect. | ||
| 592 | + | ||
| 593 | + By default, all `FSWatcher` objects are "ref'ed", making it normally | ||
| 594 | + unnecessary to call `watcher.ref()` unless `watcher.unref()` had been | ||
| 595 | + called previously. | ||
| 596 | + | ||
| 597 | + ### `watcher.unref()` | ||
| 598 | + <!-- YAML | ||
| 599 | + added: REPLACEME | ||
| 600 | + --> | ||
| 601 | + | ||
| 602 | + * Returns: {fs.FSWatcher} | ||
| 603 | + | ||
| 604 | + When called, the active `FSWatcher` object will not require the Node.js | ||
| 605 | + event loop to remain active. If there is no other activity keeping the | ||
| 606 | + event loop running, the process may exit before the `FSWatcher` object's | ||
| 607 | + callback is invoked. Calling `watcher.unref()` multiple times will have | ||
| 608 | + no effect. | ||
| 609 | + | ||
| 610 | + ## Class: `fs.StatWatcher` | ||
| 611 | + <!-- YAML | ||
| 612 | + added: REPLACEME | ||
| 613 | + --> | ||
| 614 | + | ||
| 615 | + * Extends {EventEmitter} | ||
| 616 | + | ||
| 617 | + A successful call to `fs.watchFile()` method will return a new `fs.StatWatcher` | ||
| 618 | + object. | ||
| 619 | + | ||
| 620 | + ### `watcher.ref()` | ||
| 621 | + <!-- YAML | ||
| 622 | + added: REPLACEME | ||
| 623 | + --> | ||
| 624 | + | ||
| 625 | + * Returns: {fs.StatWatcher} | ||
| 626 | + | ||
| 627 | + When called, requests that the Node.js event loop *not* exit so long as the | ||
| 628 | + `StatWatcher` is active. Calling `watcher.ref()` multiple times will have | ||
| 629 | + no effect. | ||
| 630 | + | ||
| 631 | + By default, all `StatWatcher` objects are "ref'ed", making it normally | ||
| 632 | + unnecessary to call `watcher.ref()` unless `watcher.unref()` had been | ||
| 633 | + called previously. | ||
| 634 | + | ||
| 635 | + ### `watcher.unref()` | ||
| 636 | + <!-- YAML | ||
| 637 | + added: REPLACEME | ||
| 638 | + --> | ||
| 639 | + | ||
| 640 | + * Returns: {fs.StatWatcher} | ||
| 641 | + | ||
| 642 | + When called, the active `StatWatcher` object will not require the Node.js | ||
| 643 | + event loop to remain active. If there is no other activity keeping the | ||
| 644 | + event loop running, the process may exit before the `StatWatcher` object's | ||
| 645 | + callback is invoked. Calling `watcher.unref()` multiple times will have | ||
| 646 | + no effect. | ||
| 647 | + | ||
| 582 | 648 | ## Class: `fs.ReadStream` | |
| 583 | 649 | <!-- YAML | |
| 584 | 650 | added: v0.1.93 | |
@@ -3958,6 +4024,7 @@ changes: | |||
| 3958 | 4024 | * `listener` {Function} | |
| 3959 | 4025 | * `current` {fs.Stats} | |
| 3960 | 4026 | * `previous` {fs.Stats} | |
| 4027 | + * Returns: {fs.StatWatcher} | ||
| 3961 | 4028 | ||
| 3962 | 4029 | Watch for changes on `filename`. The callback `listener` will be called each | |
| 3963 | 4030 | time the file is accessed. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1489,6 +1489,8 @@ function watchFile(filename, options, listener) { | |||
| 1489 | 1489 | stat[watchers.kFSStatWatcherStart](filename, | |
| 1490 | 1490 | options.persistent, options.interval); | |
| 1491 | 1491 | statWatchers.set(filename, stat); | |
| 1492 | + } else { | ||
| 1493 | + stat[watchers.kFSStatWatcherAddOrCleanRef]('add'); | ||
| 1492 | 1494 | } | |
| 1493 | 1495 | ||
| 1494 | 1496 | stat.addListener('change', listener); | |
@@ -1503,9 +1505,13 @@ function unwatchFile(filename, listener) { | |||
| 1503 | 1505 | if (stat === undefined) return; | |
| 1504 | 1506 | ||
| 1505 | 1507 | if (typeof listener === 'function') { | |
| 1508 | + const beforeListenerCount = stat.listenerCount('change'); | ||
| 1506 | 1509 | stat.removeListener('change', listener); | |
| 1510 | + if (stat.listenerCount('change') < beforeListenerCount) | ||
| 1511 | + stat[watchers.kFSStatWatcherAddOrCleanRef]('clean'); | ||
| 1507 | 1512 | } else { | |
| 1508 | 1513 | stat.removeAllListeners('change'); | |
| 1514 | + stat[watchers.kFSStatWatcherAddOrCleanRef]('cleanAll'); | ||
| 1509 | 1515 | } | |
| 1510 | 1516 | ||
| 1511 | 1517 | if (stat.listenerCount('change') === 0) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -31,6 +31,9 @@ const kUseBigint = Symbol('kUseBigint'); | |||
| 31 | 31 | ||
| 32 | 32 | const kFSWatchStart = Symbol('kFSWatchStart'); | |
| 33 | 33 | const kFSStatWatcherStart = Symbol('kFSStatWatcherStart'); | |
| 34 | + const KFSStatWatcherRefCount = Symbol('KFSStatWatcherRefCount'); | ||
| 35 | + const KFSStatWatcherMaxRefCount = Symbol('KFSStatWatcherMaxRefCount'); | ||
| 36 | + const kFSStatWatcherAddOrCleanRef = Symbol('kFSStatWatcherAddOrCleanRef'); | ||
| 34 | 37 | ||
| 35 | 38 | function emitStop(self) { | |
| 36 | 39 | self.emit('stop'); | |
@@ -42,6 +45,8 @@ function StatWatcher(bigint) { | |||
| 42 | 45 | this._handle = null; | |
| 43 | 46 | this[kOldStatus] = -1; | |
| 44 | 47 | this[kUseBigint] = bigint; | |
| 48 | + this[KFSStatWatcherRefCount] = 1; | ||
| 49 | + this[KFSStatWatcherMaxRefCount] = 1; | ||
| 45 | 50 | } | |
| 46 | 51 | ObjectSetPrototypeOf(StatWatcher.prototype, EventEmitter.prototype); | |
| 47 | 52 | ObjectSetPrototypeOf(StatWatcher, EventEmitter); | |
@@ -75,7 +80,7 @@ StatWatcher.prototype[kFSStatWatcherStart] = function(filename, | |||
| 75 | 80 | this._handle[owner_symbol] = this; | |
| 76 | 81 | this._handle.onchange = onchange; | |
| 77 | 82 | if (!persistent) | |
| 78 | - this._handle.unref(); | ||
| 83 | + this.unref(); | ||
| 79 | 84 | ||
| 80 | 85 | // uv_fs_poll is a little more powerful than ev_stat but we curb it for | |
| 81 | 86 | // the sake of backwards compatibility. | |
@@ -117,6 +122,41 @@ StatWatcher.prototype.stop = function() { | |||
| 117 | 122 | this._handle = null; | |
| 118 | 123 | }; | |
| 119 | 124 | ||
| 125 | + // Clean up or add ref counters. | ||
| 126 | + StatWatcher.prototype[kFSStatWatcherAddOrCleanRef] = function(operate) { | ||
| 127 | + if (operate === 'add') { | ||
| 128 | + // Add a Ref | ||
| 129 | + this[KFSStatWatcherRefCount]++; | ||
| 130 | + this[KFSStatWatcherMaxRefCount]++; | ||
| 131 | + } else if (operate === 'clean') { | ||
| 132 | + // Clean up a single | ||
| 133 | + this[KFSStatWatcherMaxRefCount]--; | ||
| 134 | + this.unref(); | ||
| 135 | + } else if (operate === 'cleanAll') { | ||
| 136 | + // Clean up all | ||
| 137 | + this[KFSStatWatcherMaxRefCount] = 0; | ||
| 138 | + this[KFSStatWatcherRefCount] = 0; | ||
| 139 | + this._handle && this._handle.unref(); | ||
| 140 | + } | ||
| 141 | + }; | ||
| 142 | + | ||
| 143 | + StatWatcher.prototype.ref = function() { | ||
| 144 | + // Avoid refCount calling ref multiple times causing unref to have no effect. | ||
| 145 | + if (this[KFSStatWatcherRefCount] === this[KFSStatWatcherMaxRefCount]) | ||
| 146 | + return this; | ||
| 147 | + if (this._handle && this[KFSStatWatcherRefCount]++ === 0) | ||
| 148 | + this._handle.ref(); | ||
| 149 | + return this; | ||
| 150 | + }; | ||
| 151 | + | ||
| 152 | + StatWatcher.prototype.unref = function() { | ||
| 153 | + // Avoid refCount calling unref multiple times causing ref to have no effect. | ||
| 154 | + if (this[KFSStatWatcherRefCount] === 0) return this; | ||
| 155 | + if (this._handle && --this[KFSStatWatcherRefCount] === 0) | ||
| 156 | + this._handle.unref(); | ||
| 157 | + return this; | ||
| 158 | + }; | ||
| 159 | + | ||
| 120 | 160 | ||
| 121 | 161 | function FSWatcher() { | |
| 122 | 162 | EventEmitter.call(this); | |
@@ -208,6 +248,16 @@ FSWatcher.prototype.close = function() { | |||
| 208 | 248 | process.nextTick(emitCloseNT, this); | |
| 209 | 249 | }; | |
| 210 | 250 | ||
| 251 | + FSWatcher.prototype.ref = function() { | ||
| 252 | + if (this._handle) this._handle.ref(); | ||
| 253 | + return this; | ||
| 254 | + }; | ||
| 255 | + | ||
| 256 | + FSWatcher.prototype.unref = function() { | ||
| 257 | + if (this._handle) this._handle.unref(); | ||
| 258 | + return this; | ||
| 259 | + }; | ||
| 260 | + | ||
| 211 | 261 | function emitCloseNT(self) { | |
| 212 | 262 | self.emit('close'); | |
| 213 | 263 | } | |
@@ -223,5 +273,6 @@ module.exports = { | |||
| 223 | 273 | FSWatcher, | |
| 224 | 274 | StatWatcher, | |
| 225 | 275 | kFSWatchStart, | |
| 226 | - kFSStatWatcherStart | ||
| 276 | + kFSStatWatcherStart, | ||
| 277 | + kFSStatWatcherAddOrCleanRef, | ||
| 227 | 278 | }; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -101,9 +101,8 @@ void FSEventWrap::Initialize(Local<Object> target, | |||
| 101 | 101 | FSEventWrap::kInternalFieldCount); | |
| 102 | 102 | t->SetClassName(fsevent_string); | |
| 103 | 103 | ||
| 104 | - t->Inherit(AsyncWrap::GetConstructorTemplate(env)); | ||
| 104 | + t->Inherit(HandleWrap::GetConstructorTemplate(env)); | ||
| 105 | 105 | env->SetProtoMethod(t, "start", Start); | |
| 106 | - env->SetProtoMethod(t, "close", Close); | ||
| 107 | 106 | ||
| 108 | 107 | Local<FunctionTemplate> get_initialized_templ = | |
| 109 | 108 | FunctionTemplate::New(env->isolate(), | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,20 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const common = require('../common'); | ||
| 4 | + | ||
| 5 | + if (common.isIBMi) | ||
| 6 | + common.skip('IBMi does not support `fs.watch()`'); | ||
| 7 | + | ||
| 8 | + const fs = require('fs'); | ||
| 9 | + | ||
| 10 | + const watcher = fs.watch(__filename, common.mustNotCall()); | ||
| 11 | + | ||
| 12 | + watcher.unref(); | ||
| 13 | + | ||
| 14 | + setTimeout( | ||
| 15 | + common.mustCall(() => { | ||
| 16 | + watcher.ref(); | ||
| 17 | + watcher.unref(); | ||
| 18 | + }), | ||
| 19 | + common.platformTimeout(100) | ||
| 20 | + ); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,35 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const common = require('../common'); | ||
| 4 | + | ||
| 5 | + const fs = require('fs'); | ||
| 6 | + const assert = require('assert'); | ||
| 7 | + | ||
| 8 | + const uncalledListener = common.mustNotCall(); | ||
| 9 | + const uncalledListener2 = common.mustNotCall(); | ||
| 10 | + const watcher = fs.watchFile(__filename, uncalledListener); | ||
| 11 | + | ||
| 12 | + watcher.unref(); | ||
| 13 | + watcher.unref(); | ||
| 14 | + watcher.ref(); | ||
| 15 | + watcher.unref(); | ||
| 16 | + watcher.ref(); | ||
| 17 | + watcher.ref(); | ||
| 18 | + watcher.unref(); | ||
| 19 | + | ||
| 20 | + fs.unwatchFile(__filename, uncalledListener); | ||
| 21 | + | ||
| 22 | + // Watch the file with two different listeners. | ||
| 23 | + fs.watchFile(__filename, uncalledListener); | ||
| 24 | + const watcher2 = fs.watchFile(__filename, uncalledListener2); | ||
| 25 | + | ||
| 26 | + setTimeout( | ||
| 27 | + common.mustCall(() => { | ||
| 28 | + fs.unwatchFile(__filename, common.mustNotCall()); | ||
| 29 | + assert.strictEqual(watcher2.listenerCount('change'), 2); | ||
| 30 | + fs.unwatchFile(__filename, uncalledListener); | ||
| 31 | + assert.strictEqual(watcher2.listenerCount('change'), 1); | ||
| 32 | + watcher2.unref(); | ||
| 33 | + }), | ||
| 34 | + common.platformTimeout(100) | ||
| 35 | + ); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -84,6 +84,7 @@ const customTypesMap = { | |||
| 84 | 84 | 'fs.FSWatcher': 'fs.html#fs_class_fs_fswatcher', | |
| 85 | 85 | 'fs.ReadStream': 'fs.html#fs_class_fs_readstream', | |
| 86 | 86 | 'fs.Stats': 'fs.html#fs_class_fs_stats', | |
| 87 | + 'fs.StatWatcher': 'fs.html#fs_class_fs_statwatcher', | ||
| 87 | 88 | 'fs.WriteStream': 'fs.html#fs_class_fs_writestream', | |
| 88 | 89 | ||
| 89 | 90 | 'http.Agent': 'http.html#http_class_http_agent', | |
| Back | FazBrowse Home | New Git URL |
0 commit comments