@@ -27,6 +27,13 @@ var binding = process.binding('net');
2727var FreeList = require ( 'freelist' ) . FreeList ;
2828
2929var IOWatcher = process . binding ( 'io_watcher' ) . IOWatcher ;
30+
31+ var ioAlloc = process . binding ( 'io_watcher' ) . ioAlloc ;
32+ var ioFree = process . binding ( 'io_watcher' ) . ioFree ;
33+ var ioStop = process . binding ( 'io_watcher' ) . ioStop ;
34+ var ioStart = process . binding ( 'io_watcher' ) . ioStart ;
35+ var ioSet = process . binding ( 'io_watcher' ) . ioSet ;
36+
3037var constants = process . binding ( 'constants' ) ;
3138var assert = process . assert ;
3239
@@ -820,73 +827,74 @@ function Server(/* [ options, ] listener */) {
820827 self . connections = 0 ;
821828
822829 self . allowHalfOpen = options . allowHalfOpen || false ;
830+ }
831+ util . inherits ( Server , events . EventEmitter ) ;
832+ exports . Server = Server ;
823833
824- self . watcher = new IOWatcher ( ) ;
825- self . watcher . host = self ;
826- self . watcher . callback = function ( ) {
827- // Just in case we don't have a dummy fd.
828- getDummyFD ( ) ;
829834
830- if ( self . _pauseTimer ) {
831- // Somehow the watcher got started again. Need to wait until
832- // the timer finishes.
833- self . watcher . stop ( ) ;
834- }
835+ exports . createServer = function ( ) {
836+ return new Server ( arguments [ 0 ] , arguments [ 1 ] ) ;
837+ } ;
835838
836- while ( self . fd ) {
837- try {
838- var peerInfo = accept ( self . fd ) ;
839- } catch ( e ) {
840- if ( e . errno != EMFILE ) throw e ;
841839
842- // Gracefully reject pending clients by freeing up a file
843- // descriptor.
844- rescueEMFILE ( function ( ) {
845- self . _rejectPending ( ) ;
846- } ) ;
847- return ;
848- }
849- if ( ! peerInfo ) return ;
840+ Server . prototype . _onIO = function ( watcher , readable , writable ) {
841+ var self = this ;
850842
851- if ( self . maxConnections && self . connections >= self . maxConnections ) {
852- // Close the connection we just had
853- close ( peerInfo . fd ) ;
854- // Reject all other pending connectins.
855- self . _rejectPending ( ) ;
856- return ;
857- }
843+ // Just in case we don't have a dummy fd.
844+ getDummyFD ( ) ;
858845
859- self . connections ++ ;
846+ if ( self . _pauseTimer ) {
847+ // Somehow the watcher got started again. Need to wait until
848+ // the timer finishes.
849+ ioStop ( watcher ) ;
850+ }
860851
861- var options = { fd : peerInfo . fd ,
862- type : self . type ,
863- allowHalfOpen : self . allowHalfOpen } ;
864- var s = new Socket ( options ) ;
865- s . remoteAddress = peerInfo . address ;
866- s . remotePort = peerInfo . port ;
867- s . type = self . type ;
868- s . server = self ;
869- s . resume ( ) ;
852+ while ( self . fd ) {
853+ try {
854+ var peerInfo = accept ( self . fd ) ;
855+ } catch ( e ) {
856+ if ( e . errno != EMFILE ) throw e ;
870857
871- self . emit ( 'connection' , s ) ;
858+ // Gracefully reject pending clients by freeing up a file
859+ // descriptor.
860+ rescueEMFILE ( function ( ) {
861+ self . _rejectPending ( ) ;
862+ } ) ;
863+ return ;
864+ }
865+ if ( ! peerInfo ) return ;
872866
873- // The 'connect' event probably should be removed for server-side
874- // sockets. It's redundant.
875- try {
876- s . emit ( 'connect' ) ;
877- } catch ( e ) {
878- s . destroy ( e ) ;
879- return ;
880- }
867+ if ( self . maxConnections && self . connections >= self . maxConnections ) {
868+ // Close the connection we just had
869+ close ( peerInfo . fd ) ;
870+ // Reject all other pending connectins.
871+ self . _rejectPending ( ) ;
872+ return ;
881873 }
882- } ;
883- }
884- util . inherits ( Server , events . EventEmitter ) ;
885- exports . Server = Server ;
886874
875+ self . connections ++ ;
887876
888- exports . createServer = function ( ) {
889- return new Server ( arguments [ 0 ] , arguments [ 1 ] ) ;
877+ var options = { fd : peerInfo . fd ,
878+ type : self . type ,
879+ allowHalfOpen : self . allowHalfOpen } ;
880+ var s = new Socket ( options ) ;
881+ s . remoteAddress = peerInfo . address ;
882+ s . remotePort = peerInfo . port ;
883+ s . type = self . type ;
884+ s . server = self ;
885+ s . resume ( ) ;
886+
887+ self . emit ( 'connection' , s ) ;
888+
889+ // The 'connect' event probably should be removed for server-side
890+ // sockets. It's redundant.
891+ try {
892+ s . emit ( 'connect' ) ;
893+ } catch ( e ) {
894+ s . destroy ( e ) ;
895+ return ;
896+ }
897+ }
890898} ;
891899
892900
@@ -899,15 +907,18 @@ Server.prototype.pause = function(msecs) {
899907 var self = this ;
900908 msecs = msecs || 1000 ;
901909
902- this . watcher . stop ( ) ;
910+ assert ( this . watcher ) ;
911+ ioStop ( this . watcher ) ;
903912
904913 // Wait a second before accepting more.
905914 this . _pauseTimer = setTimeout ( function ( ) {
906915 // Our fd should still be there. If someone calls server.close() then
907916 // the pauseTimer should be cleared.
908917 assert ( parseInt ( self . fd ) >= 0 ) ;
909918 self . _pauseTimer = null ;
910- self . watcher . start ( ) ;
919+
920+ assert ( self . watcher ) ;
921+ ioStart ( self . watcher ) ;
911922 } , msecs ) ;
912923} ;
913924
@@ -931,6 +942,16 @@ Server.prototype._rejectPending = function() {
931942} ;
932943
933944
945+ Server . prototype . _getFD = function ( type ) {
946+ assert ( ! this . fd ) ;
947+ assert ( ! this . watcher ) ;
948+
949+ this . type = type ;
950+ this . fd = socket ( type ) ;
951+ this . watcher = ioAlloc ( this ) ;
952+ } ;
953+
954+
934955// Listen on a UNIX socket
935956// server.listen('/tmp/socket');
936957//
@@ -953,13 +974,11 @@ Server.prototype.listen = function() {
953974 if ( arguments . length == 0 || typeof arguments [ 0 ] == 'function' ) {
954975 // Don't bind(). OS will assign a port with INADDR_ANY.
955976 // The port can be found with server.address()
956- self . type = 'tcp4' ;
957- self . fd = socket ( self . type ) ;
977+ self . _getFD ( 'tcp4' ) ;
958978 self . _doListen ( port ) ;
959979 } else if ( port === false ) {
960980 // the first argument specifies a path
961- self . fd = socket ( 'unix' ) ;
962- self . type = 'unix' ;
981+ self . _getFD ( 'unix' ) ;
963982 var path = arguments [ 0 ] ;
964983 self . path = path ;
965984 // unlink sockfile if it exists
@@ -987,8 +1006,7 @@ Server.prototype.listen = function() {
9871006 if ( err ) {
9881007 self . emit ( 'error' , err ) ;
9891008 } else {
990- self . type = addressType == 4 ? 'tcp4' : 'tcp6' ;
991- self . fd = socket ( self . type ) ;
1009+ self . _getFD ( addressType == 4 ? 'tcp4' : 'tcp6' ) ;
9921010 self . _doListen ( port , ip ) ;
9931011 }
9941012 } ) ;
@@ -1002,12 +1020,14 @@ Server.prototype.listenFD = function(fd, type) {
10021020
10031021 this . fd = fd ;
10041022 this . type = type || null ;
1023+ this . watcher = ioAlloc ( this ) ;
10051024 this . _startWatcher ( ) ;
10061025} ;
10071026
10081027Server . prototype . _startWatcher = function ( ) {
1009- this . watcher . set ( this . fd , true , false ) ;
1010- this . watcher . start ( ) ;
1028+ assert ( this . watcher ) ;
1029+ ioSet ( this . watcher , this . fd , true , false ) ;
1030+ ioStart ( this . watcher ) ;
10111031 this . emit ( 'listening' ) ;
10121032} ;
10131033
@@ -1053,7 +1073,9 @@ Server.prototype.close = function() {
10531073 var self = this ;
10541074 if ( ! self . fd ) throw new Error ( 'Not running' ) ;
10551075
1056- self . watcher . stop ( ) ;
1076+ ioStop ( self . watcher ) ;
1077+ ioFree ( self . watcher ) ;
1078+ self . watcher = null ;
10571079
10581080 close ( self . fd ) ;
10591081 self . fd = null ;
0 commit comments