@@ -29,6 +29,10 @@ const assert = require('internal/assert');
2929const kOldStatus = Symbol ( 'kOldStatus' ) ;
3030const kUseBigint = Symbol ( 'kUseBigint' ) ;
3131
32+ const KFSStatWatcherRefCount = Symbol ( 'KFSStatWatcherRefCount' ) ;
33+ const KFSStatWatcherMaxRefCount = Symbol ( 'KFSStatWatcherMaxRefCount' ) ;
34+ const kFSStatWatcherAddOrCleanRef = Symbol ( 'kFSStatWatcherAddOrCleanRef' ) ;
35+
3236function emitStop ( self ) {
3337 self . emit ( 'stop' ) ;
3438}
@@ -39,6 +43,8 @@ function StatWatcher(bigint) {
3943 this . _handle = null ;
4044 this [ kOldStatus ] = - 1 ;
4145 this [ kUseBigint ] = bigint ;
46+ this [ KFSStatWatcherRefCount ] = 1 ;
47+ this [ KFSStatWatcherMaxRefCount ] = 1 ;
4248}
4349ObjectSetPrototypeOf ( StatWatcher . prototype , EventEmitter . prototype ) ;
4450ObjectSetPrototypeOf ( StatWatcher , EventEmitter ) ;
@@ -70,7 +76,7 @@ StatWatcher.prototype.start = function(filename, persistent, interval) {
7076 this . _handle [ owner_symbol ] = this ;
7177 this . _handle . onchange = onchange ;
7278 if ( ! persistent )
73- this . _handle . unref ( ) ;
79+ this . unref ( ) ;
7480
7581 // uv_fs_poll is a little more powerful than ev_stat but we curb it for
7682 // the sake of backwards compatibility
@@ -106,6 +112,41 @@ StatWatcher.prototype.stop = function() {
106112 this . _handle = null ;
107113} ;
108114
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+
109150
110151function FSWatcher ( ) {
111152 EventEmitter . call ( this ) ;
@@ -193,6 +234,16 @@ FSWatcher.prototype.close = function() {
193234 process . nextTick ( emitCloseNT , this ) ;
194235} ;
195236
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+
196247function emitCloseNT ( self ) {
197248 self . emit ( 'close' ) ;
198249}
@@ -206,5 +257,6 @@ ObjectDefineProperty(FSEvent.prototype, 'owner', {
206257
207258module . exports = {
208259 FSWatcher,
209- StatWatcher
260+ StatWatcher,
261+ kFSStatWatcherAddOrCleanRef,
210262} ;
0 commit comments