@@ -255,6 +255,12 @@ ReadStream.prototype._read = function(n) {
255255} ;
256256
257257ReadStream . 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).
258264 if ( this [ kIsPerformingIO ] ) {
259265 this . once ( kIoDone , ( er ) => close ( this , err || er , cb ) ) ;
260266 } else {
@@ -416,12 +422,19 @@ WriteStream.prototype._writev = function(data, cb) {
416422} ;
417423
418424WriteStream . 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).
419431 if ( this [ kIsPerformingIO ] ) {
420432 this . once ( kIoDone , ( er ) => close ( this , err || er , cb ) ) ;
421433 } else {
422434 close ( this , err , cb ) ;
423435 }
424436} ;
437+
425438WriteStream . prototype . close = function ( cb ) {
426439 if ( cb ) {
427440 if ( this . closed ) {
0 commit comments