| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -598,6 +598,72 @@ added: v0.5.8 | |||
| 598 | 598 | Stop watching for changes on the given `fs.FSWatcher`. Once stopped, the | |
| 599 | 599 | `fs.FSWatcher` object is no longer usable. | |
| 600 | 600 | ||
| 601 | + ### `watcher.ref()` | ||
| 602 | + <!-- YAML | ||
| 603 | + added: REPLACEME | ||
| 604 | + --> | ||
| 605 | + | ||
| 606 | + * Returns: {fs.FSWatcher} | ||
| 607 | + | ||
| 608 | + When called, requests that the Node.js event loop *not* exit so long as the | ||
| 609 | + `FSWatcher` is active. Calling `watcher.ref()` multiple times will have | ||
| 610 | + no effect. | ||
| 611 | + | ||
| 612 | + By default, all `FSWatcher` objects are "ref'ed", making it normally | ||
| 613 | + unnecessary to call `watcher.ref()` unless `watcher.unref()` had been | ||
| 614 | + called previously. | ||
| 615 | + | ||
| 616 | + ### `watcher.unref()` | ||
| 617 | + <!-- YAML | ||
| 618 | + added: REPLACEME | ||
| 619 | + --> | ||
| 620 | + | ||
| 621 | + * Returns: {fs.FSWatcher} | ||
| 622 | + | ||
| 623 | + When called, the active `FSWatcher` object will not require the Node.js | ||
| 624 | + event loop to remain active. If there is no other activity keeping the | ||
| 625 | + event loop running, the process may exit before the `FSWatcher` object's | ||
| 626 | + callback is invoked. Calling `watcher.unref()` multiple times will have | ||
| 627 | + no effect. | ||
| 628 | + | ||
| 629 | + ## Class: `fs.StatWatcher` | ||
| 630 | + <!-- YAML | ||
| 631 | + added: REPLACEME | ||
| 632 | + --> | ||
| 633 | + | ||
| 634 | + * Extends {EventEmitter} | ||
| 635 | + | ||
| 636 | + A successful call to `fs.watchFile()` method will return a new `fs.StatWatcher` | ||
| 637 | + object. | ||
| 638 | + | ||
| 639 | + ### `watcher.ref()` | ||
| 640 | + <!-- YAML | ||
| 641 | + added: REPLACEME | ||
| 642 | + --> | ||
| 643 | + | ||
| 644 | + * Returns: {fs.StatWatcher} | ||
| 645 | + | ||
| 646 | + When called, requests that the Node.js event loop *not* exit so long as the | ||
| 647 | + `StatWatcher` is active. Calling `watcher.ref()` multiple times will have | ||
| 648 | + no effect. | ||
| 649 | + | ||
| 650 | + By default, all `StatWatcher` objects are "ref'ed", making it normally | ||
| 651 | + unnecessary to call `watcher.ref()` unless `watcher.unref()` had been | ||
| 652 | + called previously. | ||
| 653 | + | ||
| 654 | + ### `watcher.unref()` | ||
| 655 | + <!-- YAML | ||
| 656 | + added: REPLACEME | ||
| 657 | + --> | ||
| 658 | + | ||
| 659 | + * Returns: {fs.StatWatcher} | ||
| 660 | + | ||
| 661 | + When called, the active `StatWatcher` object will not require the Node.js | ||
| 662 | + event loop to remain active. If there is no other activity keeping the | ||
| 663 | + event loop running, the process may exit before the `StatWatcher` object's | ||
| 664 | + callback is invoked. Calling `watcher.unref()` multiple times will have | ||
| 665 | + no effect. | ||
| 666 | + | ||
| 601 | 667 | ## Class: `fs.ReadStream` | |
| 602 | 668 | <!-- YAML | |
| 603 | 669 | added: v0.1.93 | |
@@ -4029,6 +4095,7 @@ changes: | |||
| 4029 | 4095 | * `listener` {Function} | |
| 4030 | 4096 | * `current` {fs.Stats} | |
| 4031 | 4097 | * `previous` {fs.Stats} | |
| 4098 | + * Returns: {fs.StatWatcher} | ||
| 4032 | 4099 | ||
| 4033 | 4100 | Watch for changes on `filename`. The callback `listener` will be called each | |
| 4034 | 4101 | time the file is accessed. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1487,6 +1487,8 @@ function watchFile(filename, options, listener) { | |||
| 1487 | 1487 | stat = new watchers.StatWatcher(options.bigint); | |
| 1488 | 1488 | stat.start(filename, options.persistent, options.interval); | |
| 1489 | 1489 | statWatchers.set(filename, stat); | |
| 1490 | + } else { | ||
| 1491 | + stat[watchers.kFSStatWatcherAddOrCleanRef]('add'); | ||
| 1490 | 1492 | } | |
| 1491 | 1493 | ||
| 1492 | 1494 | stat.addListener('change', listener); | |
@@ -1501,9 +1503,13 @@ function unwatchFile(filename, listener) { | |||
| 1501 | 1503 | if (stat === undefined) return; | |
| 1502 | 1504 | ||
| 1503 | 1505 | if (typeof listener === 'function') { | |
| 1506 | + const beforeListenerCount = stat.listenerCount('change'); | ||
| 1504 | 1507 | stat.removeListener('change', listener); | |
| 1508 | + if (stat.listenerCount('change') < beforeListenerCount) | ||
| 1509 | + stat[watchers.kFSStatWatcherAddOrCleanRef]('clean'); | ||
| 1505 | 1510 | } else { | |
| 1506 | 1511 | stat.removeAllListeners('change'); | |
| 1512 | + stat[watchers.kFSStatWatcherAddOrCleanRef]('cleanAll'); | ||
| 1507 | 1513 | } | |
| 1508 | 1514 | ||
| 1509 | 1515 | if (stat.listenerCount('change') === 0) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -29,6 +29,10 @@ const assert = require('internal/assert'); | |||
| 29 | 29 | const kOldStatus = Symbol('kOldStatus'); | |
| 30 | 30 | const kUseBigint = Symbol('kUseBigint'); | |
| 31 | 31 | ||
| 32 | + const KFSStatWatcherRefCount = Symbol('KFSStatWatcherRefCount'); | ||
| 33 | + const KFSStatWatcherMaxRefCount = Symbol('KFSStatWatcherMaxRefCount'); | ||
| 34 | + const kFSStatWatcherAddOrCleanRef = Symbol('kFSStatWatcherAddOrCleanRef'); | ||
| 35 | + | ||
| 32 | 36 | function emitStop(self) { | |
| 33 | 37 | self.emit('stop'); | |
| 34 | 38 | } | |
@@ -39,6 +43,8 @@ function StatWatcher(bigint) { | |||
| 39 | 43 | this._handle = null; | |
| 40 | 44 | this[kOldStatus] = -1; | |
| 41 | 45 | this[kUseBigint] = bigint; | |
| 46 | + this[KFSStatWatcherRefCount] = 1; | ||
| 47 | + this[KFSStatWatcherMaxRefCount] = 1; | ||
| 42 | 48 | } | |
| 43 | 49 | ObjectSetPrototypeOf(StatWatcher.prototype, EventEmitter.prototype); | |
| 44 | 50 | ObjectSetPrototypeOf(StatWatcher, EventEmitter); | |
@@ -70,7 +76,7 @@ StatWatcher.prototype.start = function(filename, persistent, interval) { | |||
| 70 | 76 | this._handle[owner_symbol] = this; | |
| 71 | 77 | this._handle.onchange = onchange; | |
| 72 | 78 | if (!persistent) | |
| 73 | - this._handle.unref(); | ||
| 79 | + this.unref(); | ||
| 74 | 80 | ||
| 75 | 81 | // uv_fs_poll is a little more powerful than ev_stat but we curb it for | |
| 76 | 82 | // the sake of backwards compatibility | |
@@ -106,6 +112,41 @@ StatWatcher.prototype.stop = function() { | |||
| 106 | 112 | this._handle = null; | |
| 107 | 113 | }; | |
| 108 | 114 | ||
| 115 | + // Clean up or add ref counters. | ||
| 116 | + StatWatcher.prototype[kFSStatWatcherAddOrCleanRef] = function(operate) { | ||
| 117 | + if (operate === 'add') { | ||
| 118 | + // Add a Ref | ||
| 119 | + this[KFSStatWatcherRefCount]++; | ||
| 120 | + this[KFSStatWatcherMaxRefCount]++; | ||
| 121 | + } else if (operate === 'clean') { | ||
| 122 | + // Clean up a single | ||
| 123 | + this[KFSStatWatcherMaxRefCount]--; | ||
| 124 | + this.unref(); | ||
| 125 | + } else if (operate === 'cleanAll') { | ||
| 126 | + // Clean up all | ||
| 127 | + this[KFSStatWatcherMaxRefCount] = 0; | ||
| 128 | + this[KFSStatWatcherRefCount] = 0; | ||
| 129 | + this._handle && this._handle.unref(); | ||
| 130 | + } | ||
| 131 | + }; | ||
| 132 | + | ||
| 133 | + StatWatcher.prototype.ref = function() { | ||
| 134 | + // Avoid refCount calling ref multiple times causing unref to have no effect. | ||
| 135 | + if (this[KFSStatWatcherRefCount] === this[KFSStatWatcherMaxRefCount]) | ||
| 136 | + return this; | ||
| 137 | + if (this._handle && this[KFSStatWatcherRefCount]++ === 0) | ||
| 138 | + this._handle.ref(); | ||
| 139 | + return this; | ||
| 140 | + }; | ||
| 141 | + | ||
| 142 | + StatWatcher.prototype.unref = function() { | ||
| 143 | + // Avoid refCount calling unref multiple times causing ref to have no effect. | ||
| 144 | + if (this[KFSStatWatcherRefCount] === 0) return this; | ||
| 145 | + if (this._handle && --this[KFSStatWatcherRefCount] === 0) | ||
| 146 | + this._handle.unref(); | ||
| 147 | + return this; | ||
| 148 | + }; | ||
| 149 | + | ||
| 109 | 150 | ||
| 110 | 151 | function FSWatcher() { | |
| 111 | 152 | EventEmitter.call(this); | |
@@ -193,6 +234,16 @@ FSWatcher.prototype.close = function() { | |||
| 193 | 234 | process.nextTick(emitCloseNT, this); | |
| 194 | 235 | }; | |
| 195 | 236 | ||
| 237 | + FSWatcher.prototype.ref = function() { | ||
| 238 | + if (this._handle) this._handle.ref(); | ||
| 239 | + return this; | ||
| 240 | + }; | ||
| 241 | + | ||
| 242 | + FSWatcher.prototype.unref = function() { | ||
| 243 | + if (this._handle) this._handle.unref(); | ||
| 244 | + return this; | ||
| 245 | + }; | ||
| 246 | + | ||
| 196 | 247 | function emitCloseNT(self) { | |
| 197 | 248 | self.emit('close'); | |
| 198 | 249 | } | |
@@ -206,5 +257,6 @@ ObjectDefineProperty(FSEvent.prototype, 'owner', { | |||
| 206 | 257 | ||
| 207 | 258 | module.exports = { | |
| 208 | 259 | FSWatcher, | |
| 209 | - StatWatcher | ||
| 260 | + StatWatcher, | ||
| 261 | + kFSStatWatcherAddOrCleanRef, | ||
| 210 | 262 | }; | |
| 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 | |
|---|---|---|---|
@@ -82,6 +82,7 @@ const customTypesMap = { | |||
| 82 | 82 | 'fs.FSWatcher': 'fs.html#fs_class_fs_fswatcher', | |
| 83 | 83 | 'fs.ReadStream': 'fs.html#fs_class_fs_readstream', | |
| 84 | 84 | 'fs.Stats': 'fs.html#fs_class_fs_stats', | |
| 85 | + 'fs.StatWatcher': 'fs.html#fs_class_fs_statwatcher', | ||
| 85 | 86 | 'fs.WriteStream': 'fs.html#fs_class_fs_writestream', | |
| 86 | 87 | ||
| 87 | 88 | 'http.Agent': 'http.html#http_class_http_agent', | |
| Back | FazBrowse Home | New Git URL |
0 commit comments