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