before writing check if the socket has been destroyed, fixes #19176

This commit is contained in:
Johannes Rieken
2017-01-24 16:47:09 +01:00
parent 1823bc0c95
commit 5c31cac04b
3 changed files with 14 additions and 6 deletions

View File

@@ -1239,6 +1239,9 @@ declare module "net" {
unref(): void;
ref(): void;
/** A Boolean value that indicates if the connection is destroyed or not. Once a connection is destroyed no further data can be transferred using it.*/
destroyed: boolean;
remoteAddress: string;
remoteFamily: string;
remotePort: number;

View File

@@ -6,7 +6,6 @@
'use strict';
import { Socket, Server as NetServer, createConnection, createServer } from 'net';
import { Duplex } from 'stream';
import { TPromise } from 'vs/base/common/winjs.base';
import Event, { Emitter, once, mapEvent } from 'vs/base/common/event';
import { fromEventEmitter } from 'vs/base/node/event';
@@ -33,7 +32,7 @@ export class Protocol implements IMessagePassingProtocol {
readonly onMessage: Event<any> = this._onMessage.event;
constructor(private stream: Duplex) {
constructor(private _socket: Socket) {
let chunks = [];
let totalLength = 0;
@@ -44,7 +43,7 @@ export class Protocol implements IMessagePassingProtocol {
bodyLen: -1,
};
stream.on('data', (data: Buffer) => {
_socket.on('data', (data: Buffer) => {
chunks.push(data);
totalLength += data.length;
@@ -139,12 +138,16 @@ export class Protocol implements IMessagePassingProtocol {
private _writeSoon(header: Buffer, data: Buffer): void {
if (this._writeBuffer.add(header, data)) {
setImmediate(() => {
// return early if socket has been destroyed in the meantime
if (this._socket.destroyed) {
return;
}
// we ignore the returned value from `write` because we would have to cached the data
// anyways and nodejs is already doing that for us:
// > https://nodejs.org/api/stream.html#stream_writable_write_chunk_encoding_callback
// > However, the false return value is only advisory and the writable stream will unconditionally
// > accept and buffer chunk even if it has not not been allowed to drain.
this.stream.write(this._writeBuffer.take());
this._socket.write(this._writeBuffer.take());
});
}
}

View File

@@ -7,7 +7,7 @@
import * as assert from 'assert';
import { TPromise } from 'vs/base/common/winjs.base';
import { Duplex } from 'stream';
import { Socket } from 'net';
import { EventEmitter } from 'events';
import { Protocol } from 'vs/base/parts/ipc/node/ipc.net';
@@ -15,6 +15,8 @@ class MockDuplex extends EventEmitter {
private _cache: Buffer[] = [];
readonly destroyed = false;
private _deliver(): void {
if (this._cache.length) {
const data = Buffer.concat(this._cache);
@@ -33,7 +35,7 @@ class MockDuplex extends EventEmitter {
suite('IPC, Socket Protocol', () => {
let stream: Duplex;
let stream: Socket;
setup(() => {
stream = <any>new MockDuplex();