@@ -255,6 +255,12 @@ ReadStream.prototype._read = function(n) {
255
255
} ;
256
256
257
257
ReadStream . prototype . _destroy = function ( err , cb ) {
258
+ // Usually for async IO it is safe to close a file descriptor
259
+ // even when there are pending operations. However, due to platform
260
+ // differences file IO is implemented using synchronous operations
261
+ // running in a thread pool. Therefore, file descriptors are not safe
262
+ // to close while used in a pending read or write operation. Wait for
263
+ // any pending IO (kIsPerformingIO) to complete (kIoDone).
258
264
if ( this [ kIsPerformingIO ] ) {
259
265
this . once ( kIoDone , ( er ) => close ( this , err || er , cb ) ) ;
260
266
} else {
@@ -416,12 +422,19 @@ WriteStream.prototype._writev = function(data, cb) {
416
422
} ;
417
423
418
424
WriteStream . prototype . _destroy = function ( err , cb ) {
425
+ // Usually for async IO it is safe to close a file descriptor
426
+ // even when there are pending operations. However, due to platform
427
+ // differences file IO is implemented using synchronous operations
428
+ // running in a thread pool. Therefore, file descriptors are not safe
429
+ // to close while used in a pending read or write operation. Wait for
430
+ // any pending IO (kIsPerformingIO) to complete (kIoDone).
419
431
if ( this [ kIsPerformingIO ] ) {
420
432
this . once ( kIoDone , ( er ) => close ( this , err || er , cb ) ) ;
421
433
} else {
422
434
close ( this , err , cb ) ;
423
435
}
424
436
} ;
437
+
425
438
WriteStream . prototype . close = function ( cb ) {
426
439
if ( cb ) {
427
440
if ( this . closed ) {
0 commit comments