@@ -84,6 +84,7 @@ function initSocketHandle(self) {
84
84
self . _flags = 0 ;
85
85
self . _connectQueueSize = 0 ;
86
86
self . destroyed = false ;
87
+ self . errorEmitted = false ;
87
88
self . bytesRead = 0 ;
88
89
self . bytesWritten = 0 ;
89
90
@@ -244,7 +245,7 @@ Socket.prototype.end = function(data, encoding) {
244
245
var shutdownReq = this . _handle . shutdown ( ) ;
245
246
246
247
if ( ! shutdownReq ) {
247
- this . destroy ( errnoException ( errno , 'shutdown' ) ) ;
248
+ this . _destroy ( errnoException ( errno , 'shutdown' ) ) ;
248
249
return false ;
249
250
}
250
251
@@ -267,7 +268,7 @@ function afterShutdown(status, handle, req) {
267
268
}
268
269
269
270
if ( self . _flags & FLAG_GOT_EOF || ! self . readable ) {
270
- self . destroy ( ) ;
271
+ self . _destroy ( ) ;
271
272
} else {
272
273
}
273
274
}
@@ -278,7 +279,7 @@ Socket.prototype.destroySoon = function() {
278
279
this . _flags |= FLAG_DESTROY_SOON ;
279
280
280
281
if ( this . _pendingWriteReqs == 0 ) {
281
- this . destroy ( ) ;
282
+ this . _destroy ( ) ;
282
283
}
283
284
} ;
284
285
@@ -290,11 +291,24 @@ Socket.prototype._connectQueueCleanUp = function(exception) {
290
291
} ;
291
292
292
293
293
- Socket . prototype . destroy = function ( exception ) {
294
- if ( this . destroyed ) return ;
295
-
294
+ Socket . prototype . _destroy = function ( exception , cb ) {
296
295
var self = this ;
297
296
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
+
298
312
self . _connectQueueCleanUp ( ) ;
299
313
300
314
debug ( 'destroy' ) ;
@@ -315,15 +329,21 @@ Socket.prototype.destroy = function(exception) {
315
329
this . _handle = null ;
316
330
}
317
331
332
+ fireErrorCallbacks ( ) ;
333
+
318
334
process . nextTick ( function ( ) {
319
- if ( exception ) self . emit ( 'error' , exception ) ;
320
335
self . emit ( 'close' , exception ? true : false ) ;
321
336
} ) ;
322
337
323
338
this . destroyed = true ;
324
339
} ;
325
340
326
341
342
+ Socket . prototype . destroy = function ( exception ) {
343
+ this . _destroy ( exception ) ;
344
+ }
345
+
346
+
327
347
function onread ( buffer , offset , length ) {
328
348
var handle = this ;
329
349
var self = handle . socket ;
@@ -362,17 +382,17 @@ function onread(buffer, offset, length) {
362
382
363
383
// We call destroy() before end(). 'close' not emitted until nextTick so
364
384
// the 'end' event will come first as required.
365
- if ( ! self . writable ) self . destroy ( ) ;
385
+ if ( ! self . writable ) self . _destroy ( ) ;
366
386
367
387
if ( ! self . allowHalfOpen ) self . end ( ) ;
368
388
if ( self . _events && self . _events [ 'end' ] ) self . emit ( 'end' ) ;
369
389
if ( self . onend ) self . onend ( ) ;
370
390
} else {
371
391
// Error
372
392
if ( errno == 'ECONNRESET' ) {
373
- self . destroy ( ) ;
393
+ self . _destroy ( ) ;
374
394
} else {
375
- self . destroy ( errnoException ( errno , 'read' ) ) ;
395
+ self . _destroy ( errnoException ( errno , 'read' ) ) ;
376
396
}
377
397
}
378
398
}
@@ -450,13 +470,16 @@ Socket.prototype.write = function(data, arg1, arg2) {
450
470
Socket . prototype . _write = function ( data , encoding , cb ) {
451
471
timers . active ( this ) ;
452
472
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
+ }
454
477
455
478
// `encoding` is unused right now, `data` is always a buffer.
456
479
var writeReq = this . _handle . write ( data ) ;
457
480
458
481
if ( ! writeReq ) {
459
- this . destroy ( errnoException ( errno , 'write' ) ) ;
482
+ this . _destroy ( errnoException ( errno , 'write' ) , cb ) ;
460
483
return false ;
461
484
}
462
485
@@ -477,7 +500,7 @@ function afterWrite(status, handle, req, buffer) {
477
500
}
478
501
479
502
if ( status ) {
480
- self . destroy ( errnoException ( errno , 'write' ) ) ;
503
+ self . _destroy ( errnoException ( errno , 'write' ) , req . cb ) ;
481
504
return ;
482
505
}
483
506
@@ -494,7 +517,7 @@ function afterWrite(status, handle, req, buffer) {
494
517
if ( req . cb ) req . cb ( ) ;
495
518
496
519
if ( self . _pendingWriteReqs == 0 && self . _flags & FLAG_DESTROY_SOON ) {
497
- self . destroy ( ) ;
520
+ self . _destroy ( ) ;
498
521
}
499
522
}
500
523
@@ -522,7 +545,7 @@ function connect(self, address, port, addressType) {
522
545
if ( connectReq !== null ) {
523
546
connectReq . oncomplete = afterConnect ;
524
547
} else {
525
- self . destroy ( errnoException ( errno , 'connect' ) ) ;
548
+ self . _destroy ( errnoException ( errno , 'connect' ) ) ;
526
549
}
527
550
}
528
551
@@ -570,7 +593,7 @@ Socket.prototype.connect = function(port /* [host], [cb] */) {
570
593
// error event to the next tick.
571
594
process . nextTick ( function ( ) {
572
595
self . emit ( 'error' , err ) ;
573
- self . destroy ( ) ;
596
+ self . _destroy ( ) ;
574
597
} ) ;
575
598
} else {
576
599
timers . active ( self ) ;
@@ -619,8 +642,9 @@ function afterConnect(status, handle, req, readable, writable) {
619
642
620
643
if ( self . _connectQueue ) {
621
644
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 ] ) ;
624
648
}
625
649
self . _connectQueueCleanUp ( ) ;
626
650
}
@@ -634,7 +658,7 @@ function afterConnect(status, handle, req, readable, writable) {
634
658
}
635
659
} else {
636
660
self . _connectQueueCleanUp ( ) ;
637
- self . destroy ( errnoException ( errno , 'connect' ) ) ;
661
+ self . _destroy ( errnoException ( errno , 'connect' ) ) ;
638
662
}
639
663
}
640
664
0 commit comments