@@ -84,6 +84,7 @@ function initSocketHandle(self) {
8484 self . _flags = 0 ;
8585 self . _connectQueueSize = 0 ;
8686 self . destroyed = false ;
87+ self . errorEmitted = false ;
8788 self . bytesRead = 0 ;
8889 self . bytesWritten = 0 ;
8990
@@ -244,7 +245,7 @@ Socket.prototype.end = function(data, encoding) {
244245 var shutdownReq = this . _handle . shutdown ( ) ;
245246
246247 if ( ! shutdownReq ) {
247- this . destroy ( errnoException ( errno , 'shutdown' ) ) ;
248+ this . _destroy ( errnoException ( errno , 'shutdown' ) ) ;
248249 return false ;
249250 }
250251
@@ -267,7 +268,7 @@ function afterShutdown(status, handle, req) {
267268 }
268269
269270 if ( self . _flags & FLAG_GOT_EOF || ! self . readable ) {
270- self . destroy ( ) ;
271+ self . _destroy ( ) ;
271272 } else {
272273 }
273274}
@@ -278,7 +279,7 @@ Socket.prototype.destroySoon = function() {
278279 this . _flags |= FLAG_DESTROY_SOON ;
279280
280281 if ( this . _pendingWriteReqs == 0 ) {
281- this . destroy ( ) ;
282+ this . _destroy ( ) ;
282283 }
283284} ;
284285
@@ -290,11 +291,24 @@ Socket.prototype._connectQueueCleanUp = function(exception) {
290291} ;
291292
292293
293- Socket . prototype . destroy = function ( exception ) {
294- if ( this . destroyed ) return ;
295-
294+ Socket . prototype . _destroy = function ( exception , cb ) {
296295 var self = this ;
297296
297+ function fireErrorCallbacks ( ) {
298+ if ( cb ) cb ( exception ) ;
299+ if ( exception && ! self . errorEmitted ) {
300+ process . nextTick ( function ( ) {
301+ self . emit ( 'error' , exception ) ;
302+ } ) ;
303+ self . errorEmitted = true ;
304+ }
305+ } ;
306+
307+ if ( this . destroyed ) {
308+ fireErrorCallbacks ( ) ;
309+ return ;
310+ }
311+
298312 self . _connectQueueCleanUp ( ) ;
299313
300314 debug ( 'destroy' ) ;
@@ -315,15 +329,21 @@ Socket.prototype.destroy = function(exception) {
315329 this . _handle = null ;
316330 }
317331
332+ fireErrorCallbacks ( ) ;
333+
318334 process . nextTick ( function ( ) {
319- if ( exception ) self . emit ( 'error' , exception ) ;
320335 self . emit ( 'close' , exception ? true : false ) ;
321336 } ) ;
322337
323338 this . destroyed = true ;
324339} ;
325340
326341
342+ Socket . prototype . destroy = function ( exception ) {
343+ this . _destroy ( exception ) ;
344+ }
345+
346+
327347function onread ( buffer , offset , length ) {
328348 var handle = this ;
329349 var self = handle . socket ;
@@ -362,17 +382,17 @@ function onread(buffer, offset, length) {
362382
363383 // We call destroy() before end(). 'close' not emitted until nextTick so
364384 // the 'end' event will come first as required.
365- if ( ! self . writable ) self . destroy ( ) ;
385+ if ( ! self . writable ) self . _destroy ( ) ;
366386
367387 if ( ! self . allowHalfOpen ) self . end ( ) ;
368388 if ( self . _events && self . _events [ 'end' ] ) self . emit ( 'end' ) ;
369389 if ( self . onend ) self . onend ( ) ;
370390 } else {
371391 // Error
372392 if ( errno == 'ECONNRESET' ) {
373- self . destroy ( ) ;
393+ self . _destroy ( ) ;
374394 } else {
375- self . destroy ( errnoException ( errno , 'read' ) ) ;
395+ self . _destroy ( errnoException ( errno , 'read' ) ) ;
376396 }
377397 }
378398}
@@ -450,13 +470,16 @@ Socket.prototype.write = function(data, arg1, arg2) {
450470Socket . prototype . _write = function ( data , encoding , cb ) {
451471 timers . active ( this ) ;
452472
453- if ( ! this . _handle ) throw new Error ( 'This socket is closed.' ) ;
473+ if ( ! this . _handle ) {
474+ this . _destroy ( new Error ( 'This socket is closed.' ) , cb ) ;
475+ return false ;
476+ }
454477
455478 // `encoding` is unused right now, `data` is always a buffer.
456479 var writeReq = this . _handle . write ( data ) ;
457480
458481 if ( ! writeReq ) {
459- this . destroy ( errnoException ( errno , 'write' ) ) ;
482+ this . _destroy ( errnoException ( errno , 'write' ) , cb ) ;
460483 return false ;
461484 }
462485
@@ -477,7 +500,7 @@ function afterWrite(status, handle, req, buffer) {
477500 }
478501
479502 if ( status ) {
480- self . destroy ( errnoException ( errno , 'write' ) ) ;
503+ self . _destroy ( errnoException ( errno , 'write' ) , req . cb ) ;
481504 return ;
482505 }
483506
@@ -494,7 +517,7 @@ function afterWrite(status, handle, req, buffer) {
494517 if ( req . cb ) req . cb ( ) ;
495518
496519 if ( self . _pendingWriteReqs == 0 && self . _flags & FLAG_DESTROY_SOON ) {
497- self . destroy ( ) ;
520+ self . _destroy ( ) ;
498521 }
499522}
500523
@@ -522,7 +545,7 @@ function connect(self, address, port, addressType) {
522545 if ( connectReq !== null ) {
523546 connectReq . oncomplete = afterConnect ;
524547 } else {
525- self . destroy ( errnoException ( errno , 'connect' ) ) ;
548+ self . _destroy ( errnoException ( errno , 'connect' ) ) ;
526549 }
527550}
528551
@@ -570,7 +593,7 @@ Socket.prototype.connect = function(port /* [host], [cb] */) {
570593 // error event to the next tick.
571594 process . nextTick ( function ( ) {
572595 self . emit ( 'error' , err ) ;
573- self . destroy ( ) ;
596+ self . _destroy ( ) ;
574597 } ) ;
575598 } else {
576599 timers . active ( self ) ;
@@ -619,8 +642,9 @@ function afterConnect(status, handle, req, readable, writable) {
619642
620643 if ( self . _connectQueue ) {
621644 debug ( 'Drain the connect queue' ) ;
622- for ( var i = 0 ; i < self . _connectQueue . length ; i ++ ) {
623- self . _write . apply ( self , self . _connectQueue [ i ] ) ;
645+ var connectQueue = self . _connectQueue ;
646+ for ( var i = 0 ; i < connectQueue . length ; i ++ ) {
647+ self . _write . apply ( self , connectQueue [ i ] ) ;
624648 }
625649 self . _connectQueueCleanUp ( ) ;
626650 }
@@ -634,7 +658,7 @@ function afterConnect(status, handle, req, readable, writable) {
634658 }
635659 } else {
636660 self . _connectQueueCleanUp ( ) ;
637- self . destroy ( errnoException ( errno , 'connect' ) ) ;
661+ self . _destroy ( errnoException ( errno , 'connect' ) ) ;
638662 }
639663}
640664
0 commit comments