You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					105 lines
				
				3.0 KiB
			
		
		
			
		
	
	
					105 lines
				
				3.0 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								'use strict'; // undocumented cb() API, needed for core, not for public API
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function destroy(err, cb) {
							 | 
						||
| 
								 | 
							
								  var _this = this;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var readableDestroyed = this._readableState && this._readableState.destroyed;
							 | 
						||
| 
								 | 
							
								  var writableDestroyed = this._writableState && this._writableState.destroyed;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (readableDestroyed || writableDestroyed) {
							 | 
						||
| 
								 | 
							
								    if (cb) {
							 | 
						||
| 
								 | 
							
								      cb(err);
							 | 
						||
| 
								 | 
							
								    } else if (err) {
							 | 
						||
| 
								 | 
							
								      if (!this._writableState) {
							 | 
						||
| 
								 | 
							
								        process.nextTick(emitErrorNT, this, err);
							 | 
						||
| 
								 | 
							
								      } else if (!this._writableState.errorEmitted) {
							 | 
						||
| 
								 | 
							
								        this._writableState.errorEmitted = true;
							 | 
						||
| 
								 | 
							
								        process.nextTick(emitErrorNT, this, err);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return this;
							 | 
						||
| 
								 | 
							
								  } // we set destroyed to true before firing error callbacks in order
							 | 
						||
| 
								 | 
							
								  // to make it re-entrance safe in case destroy() is called within callbacks
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (this._readableState) {
							 | 
						||
| 
								 | 
							
								    this._readableState.destroyed = true;
							 | 
						||
| 
								 | 
							
								  } // if this is a duplex stream mark the writable part as destroyed as well
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (this._writableState) {
							 | 
						||
| 
								 | 
							
								    this._writableState.destroyed = true;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this._destroy(err || null, function (err) {
							 | 
						||
| 
								 | 
							
								    if (!cb && err) {
							 | 
						||
| 
								 | 
							
								      if (!_this._writableState) {
							 | 
						||
| 
								 | 
							
								        process.nextTick(emitErrorAndCloseNT, _this, err);
							 | 
						||
| 
								 | 
							
								      } else if (!_this._writableState.errorEmitted) {
							 | 
						||
| 
								 | 
							
								        _this._writableState.errorEmitted = true;
							 | 
						||
| 
								 | 
							
								        process.nextTick(emitErrorAndCloseNT, _this, err);
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        process.nextTick(emitCloseNT, _this);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    } else if (cb) {
							 | 
						||
| 
								 | 
							
								      process.nextTick(emitCloseNT, _this);
							 | 
						||
| 
								 | 
							
								      cb(err);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      process.nextTick(emitCloseNT, _this);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return this;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function emitErrorAndCloseNT(self, err) {
							 | 
						||
| 
								 | 
							
								  emitErrorNT(self, err);
							 | 
						||
| 
								 | 
							
								  emitCloseNT(self);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function emitCloseNT(self) {
							 | 
						||
| 
								 | 
							
								  if (self._writableState && !self._writableState.emitClose) return;
							 | 
						||
| 
								 | 
							
								  if (self._readableState && !self._readableState.emitClose) return;
							 | 
						||
| 
								 | 
							
								  self.emit('close');
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function undestroy() {
							 | 
						||
| 
								 | 
							
								  if (this._readableState) {
							 | 
						||
| 
								 | 
							
								    this._readableState.destroyed = false;
							 | 
						||
| 
								 | 
							
								    this._readableState.reading = false;
							 | 
						||
| 
								 | 
							
								    this._readableState.ended = false;
							 | 
						||
| 
								 | 
							
								    this._readableState.endEmitted = false;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (this._writableState) {
							 | 
						||
| 
								 | 
							
								    this._writableState.destroyed = false;
							 | 
						||
| 
								 | 
							
								    this._writableState.ended = false;
							 | 
						||
| 
								 | 
							
								    this._writableState.ending = false;
							 | 
						||
| 
								 | 
							
								    this._writableState.finalCalled = false;
							 | 
						||
| 
								 | 
							
								    this._writableState.prefinished = false;
							 | 
						||
| 
								 | 
							
								    this._writableState.finished = false;
							 | 
						||
| 
								 | 
							
								    this._writableState.errorEmitted = false;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function emitErrorNT(self, err) {
							 | 
						||
| 
								 | 
							
								  self.emit('error', err);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function errorOrDestroy(stream, err) {
							 | 
						||
| 
								 | 
							
								  // We have tests that rely on errors being emitted
							 | 
						||
| 
								 | 
							
								  // in the same tick, so changing this is semver major.
							 | 
						||
| 
								 | 
							
								  // For now when you opt-in to autoDestroy we allow
							 | 
						||
| 
								 | 
							
								  // the error to be emitted nextTick. In a future
							 | 
						||
| 
								 | 
							
								  // semver major update we should change the default to this.
							 | 
						||
| 
								 | 
							
								  var rState = stream._readableState;
							 | 
						||
| 
								 | 
							
								  var wState = stream._writableState;
							 | 
						||
| 
								 | 
							
								  if (rState && rState.autoDestroy || wState && wState.autoDestroy) stream.destroy(err);else stream.emit('error', err);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = {
							 | 
						||
| 
								 | 
							
								  destroy: destroy,
							 | 
						||
| 
								 | 
							
								  undestroy: undestroy,
							 | 
						||
| 
								 | 
							
								  errorOrDestroy: errorOrDestroy
							 | 
						||
| 
								 | 
							
								};
							 |