destroy.js 2.1 KB

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