@@ -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
} ;
0 commit comments