apply time-based limit

This commit is contained in:
Jörg Breitbart
2019-05-11 23:10:18 +02:00
parent 7549ca59be
commit 7a567d2717
+74 -7
View File
@@ -183,6 +183,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
// user input states
public writeBuffer: string[];
public writeBufferUtf8: Uint8Array[];
private _writeInProgress: boolean;
/**
@@ -340,6 +341,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
// user input states
this.writeBuffer = [];
this.writeBufferUtf8 = [];
this._writeInProgress = false;
this._xoffSentToCatchUp = false;
@@ -1366,20 +1368,85 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
}
/**
* Writes utf8 data to the terminal.
* TODO: This currently does no flow control.
* Writes raw utf8 bytes to the terminal.
* @param data The text to write to the terminal.
*/
public writeUtf8(data: Uint8Array): void {
// Ensure the terminal isn't disposed
if (this._isDisposed) {
return;
}
this._refreshStart = this.buffer.y;
this._refreshEnd = this.buffer.y;
this._inputHandler.parseUtf8(data);
// Ignore falsy data values (including the empty string)
if (!data) {
return;
}
this.updateRange(this.buffer.y);
this.refresh(this._refreshStart, this._refreshEnd);
this.writeBufferUtf8.push(data);
// Send XOFF to pause the pty process if the write buffer becomes too large so
// xterm.js can catch up before more data is sent. This is necessary in order
// to keep signals such as ^C responsive.
if (this.options.useFlowControl && !this._xoffSentToCatchUp && this.writeBufferUtf8.length >= WRITE_BUFFER_PAUSE_THRESHOLD) {
// XOFF - stop pty pipe
// XON will be triggered by emulator before processing data chunk
this.handler(C0.DC3);
this._xoffSentToCatchUp = true;
}
if (!this._writeInProgress && this.writeBufferUtf8.length > 0) {
// Kick off a write which will write all data in sequence recursively
this._writeInProgress = true;
// Kick off an async innerWrite so more writes can come in while processing data
setTimeout(() => {
this._innerWriteUtf8();
});
}
}
protected _innerWriteUtf8(bufferOffset: number = 0): void {
// Ensure the terminal isn't disposed
if (this._isDisposed) {
this.writeBufferUtf8 = [];
}
const startTime = Date.now();
while (this.writeBufferUtf8.length > bufferOffset) {
const data = this.writeBufferUtf8[bufferOffset];
bufferOffset++;
// If XOFF was sent in order to catch up with the pty process, resume it if
// we reached the end of the writeBuffer to allow more data to come in.
if (this._xoffSentToCatchUp && this.writeBufferUtf8.length === bufferOffset) {
this.handler(C0.DC1);
this._xoffSentToCatchUp = false;
}
this._refreshStart = this.buffer.y;
this._refreshEnd = this.buffer.y;
// HACK: Set the parser state based on it's state at the time of return.
// This works around the bug #662 which saw the parser state reset in the
// middle of parsing escape sequence in two chunks. For some reason the
// state of the parser resets to 0 after exiting parser.parse. This change
// just sets the state back based on the correct return statement.
this._inputHandler.parseUtf8(data);
this.updateRange(this.buffer.y);
this.refresh(this._refreshStart, this._refreshEnd);
if (Date.now() - startTime >= WRITE_TIMEOUT_MS) {
break;
}
}
if (this.writeBufferUtf8.length > bufferOffset) {
// Allow renderer to catch up before processing the next batch
setTimeout(() => this._innerWriteUtf8(bufferOffset), 0);
} else {
this._writeInProgress = false;
this.writeBufferUtf8 = [];
}
}
/**