@@ -18,6 +18,13 @@ import { findExecutable } from 'vs/workbench/contrib/terminal/node/terminalEnvir
1818import { URI } from 'vs/base/common/uri' ;
1919import { localize } from 'vs/nls' ;
2020
21+ // Writing large amounts of data can be corrupted for some reason, after looking into this is
22+ // appears to be a race condition around writing to the FD which may be based on how powerful the
23+ // hardware is. The workaround for this is to space out when large amounts of data is being written
24+ // to the terminal. See https://github.com/microsoft/vscode/issues/38137
25+ const WRITE_MAX_CHUNK_SIZE = 50 ;
26+ const WRITE_INTERVAL_MS = 5 ;
27+
2128export class TerminalProcess extends Disposable implements ITerminalChildProcess {
2229 private _exitCode : number | undefined ;
2330 private _exitMessage : string | undefined ;
@@ -27,6 +34,8 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
2734 private _processStartupComplete : Promise < void > | undefined ;
2835 private _isDisposed : boolean = false ;
2936 private _titleInterval : NodeJS . Timer | null = null ;
37+ private _writeQueue : string [ ] = [ ] ;
38+ private _writeTimeout : NodeJS . Timeout | undefined ;
3039 private readonly _initialCwd : string ;
3140 private readonly _ptyOptions : pty . IPtyForkOptions | pty . IWindowsPtyForkOptions ;
3241
@@ -232,8 +241,37 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
232241 if ( this . _isDisposed || ! this . _ptyProcess ) {
233242 return ;
234243 }
244+ for ( let i = 0 ; i <= Math . floor ( data . length / WRITE_MAX_CHUNK_SIZE ) ; i ++ ) {
245+ this . _writeQueue . push ( data . substr ( i * WRITE_MAX_CHUNK_SIZE , WRITE_MAX_CHUNK_SIZE ) ) ;
246+ }
247+ this . _startWrite ( ) ;
248+ }
249+
250+ private _startWrite ( ) : void {
251+ // Don't write if it's already queued of is there is nothing to write
252+ if ( this . _writeTimeout !== undefined || this . _writeQueue . length === 0 ) {
253+ return ;
254+ }
255+
256+ this . _doWrite ( ) ;
257+
258+ // Don't queue more writes if the queue is empty
259+ if ( this . _writeQueue . length === 0 ) {
260+ this . _writeTimeout = undefined ;
261+ return ;
262+ }
263+
264+ // Queue the next write
265+ this . _writeTimeout = setTimeout ( ( ) => {
266+ this . _writeTimeout = undefined ;
267+ this . _startWrite ( ) ;
268+ } , WRITE_INTERVAL_MS ) ;
269+ }
270+
271+ private _doWrite ( ) : void {
272+ const data = this . _writeQueue . shift ( ) ! ;
235273 this . _logService . trace ( 'IPty#write' , `${ data . length } characters` ) ;
236- this . _ptyProcess . write ( data ) ;
274+ this . _ptyProcess ! . write ( data ) ;
237275 }
238276
239277 public resize ( cols : number , rows : number ) : void {
0 commit comments