@@ -31,6 +31,9 @@ const kUseBigint = Symbol('kUseBigint');
3131
3232const kFSWatchStart = Symbol ( 'kFSWatchStart' ) ;
3333const kFSStatWatcherStart = Symbol ( 'kFSStatWatcherStart' ) ;
34+ const KFSStatWatcherRefCount = Symbol ( 'KFSStatWatcherRefCount' ) ;
35+ const KFSStatWatcherMaxRefCount = Symbol ( 'KFSStatWatcherMaxRefCount' ) ;
36+ const kFSStatWatcherAddOrCleanRef = Symbol ( 'kFSStatWatcherAddOrCleanRef' ) ;
3437
3538function emitStop ( self ) {
3639 self . emit ( 'stop' ) ;
@@ -42,6 +45,8 @@ function StatWatcher(bigint) {
4245 this . _handle = null ;
4346 this [ kOldStatus ] = - 1 ;
4447 this [ kUseBigint ] = bigint ;
48+ this [ KFSStatWatcherRefCount ] = 1 ;
49+ this [ KFSStatWatcherMaxRefCount ] = 1 ;
4550}
4651ObjectSetPrototypeOf ( StatWatcher . prototype , EventEmitter . prototype ) ;
4752ObjectSetPrototypeOf ( StatWatcher , EventEmitter ) ;
@@ -75,7 +80,7 @@ StatWatcher.prototype[kFSStatWatcherStart] = function(filename,
7580 this . _handle [ owner_symbol ] = this ;
7681 this . _handle . onchange = onchange ;
7782 if ( ! persistent )
78- this . _handle . unref ( ) ;
83+ this . unref ( ) ;
7984
8085 // uv_fs_poll is a little more powerful than ev_stat but we curb it for
8186 // the sake of backwards compatibility.
@@ -117,6 +122,41 @@ StatWatcher.prototype.stop = function() {
117122 this . _handle = null ;
118123} ;
119124
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+
120160
121161function FSWatcher ( ) {
122162 EventEmitter . call ( this ) ;
@@ -208,6 +248,16 @@ FSWatcher.prototype.close = function() {
208248 process . nextTick ( emitCloseNT , this ) ;
209249} ;
210250
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+
211261function emitCloseNT ( self ) {
212262 self . emit ( 'close' ) ;
213263}
@@ -223,5 +273,6 @@ module.exports = {
223273 FSWatcher,
224274 StatWatcher,
225275 kFSWatchStart,
226- kFSStatWatcherStart
276+ kFSStatWatcherStart,
277+ kFSStatWatcherAddOrCleanRef,
227278} ;
0 commit comments