@@ -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