destroy.js (1849B)
1 'use strict'; 2 3 /*<replacement>*/ 4 5 var pna = require('process-nextick-args'); 6 /*</replacement>*/ 7 8 // undocumented cb() API, needed for core, not for public API 9 function destroy(err, cb) { 10 var _this = this; 11 12 var readableDestroyed = this._readableState && this._readableState.destroyed; 13 var writableDestroyed = this._writableState && this._writableState.destroyed; 14 15 if (readableDestroyed || writableDestroyed) { 16 if (cb) { 17 cb(err); 18 } else if (err && (!this._writableState || !this._writableState.errorEmitted)) { 19 pna.nextTick(emitErrorNT, this, err); 20 } 21 return this; 22 } 23 24 // we set destroyed to true before firing error callbacks in order 25 // to make it re-entrance safe in case destroy() is called within callbacks 26 27 if (this._readableState) { 28 this._readableState.destroyed = true; 29 } 30 31 // if this is a duplex stream mark the writable part as destroyed as well 32 if (this._writableState) { 33 this._writableState.destroyed = true; 34 } 35 36 this._destroy(err || null, function (err) { 37 if (!cb && err) { 38 pna.nextTick(emitErrorNT, _this, err); 39 if (_this._writableState) { 40 _this._writableState.errorEmitted = true; 41 } 42 } else if (cb) { 43 cb(err); 44 } 45 }); 46 47 return this; 48 } 49 50 function undestroy() { 51 if (this._readableState) { 52 this._readableState.destroyed = false; 53 this._readableState.reading = false; 54 this._readableState.ended = false; 55 this._readableState.endEmitted = false; 56 } 57 58 if (this._writableState) { 59 this._writableState.destroyed = false; 60 this._writableState.ended = false; 61 this._writableState.ending = false; 62 this._writableState.finished = false; 63 this._writableState.errorEmitted = false; 64 } 65 } 66 67 function emitErrorNT(self, err) { 68 self.emit('error', err); 69 } 70 71 module.exports = { 72 destroy: destroy, 73 undestroy: undestroy 74 };