@@ -401,7 +401,9 @@ impl Server {
401401 let reaper_tx_child = reaper_tx. clone ( ) ;
402402 let pipe_connection_child = pipe_connection. clone ( ) ;
403403
404- let handler = thread:: Builder :: new ( )
404+ let ( sync_tx, sync_rx) = channel ( ) ;
405+
406+ let _ = thread:: Builder :: new ( )
405407 . name ( "client_handler" . into ( ) )
406408 . spawn ( move || {
407409 debug ! ( "Got new client" ) ;
@@ -505,25 +507,38 @@ impl Server {
505507 drop ( workload_rx) ;
506508 handler. join ( ) . unwrap_or ( ( ) ) ;
507509 reader. join ( ) . unwrap_or ( ( ) ) ;
510+
511+ //wait untile this connection had been inserted connections map;
512+ sync_rx. recv ( ) . unwrap_or ( ( ) ) ;
513+
508514 // client_handler should not close fd before exit
509515 // , which prevent fd reuse issue.
510516 reaper_tx_child. send ( pipe. id ( ) ) . unwrap ( ) ;
511517
512518 debug ! ( "client thread quit" ) ;
513519 } )
514- . unwrap ( ) ;
515-
516- let mut cns = connections. lock ( ) . unwrap ( ) ;
517-
518- let id = pipe_connection. id ( ) ;
519- cns. insert (
520- id,
521- Connection {
522- connection : pipe_connection,
523- handler : Some ( handler) ,
524- quit : quit. clone ( ) ,
525- } ,
526- ) ;
520+ . map ( |handler| {
521+ let mut cns = connections. lock ( ) . unwrap ( ) ;
522+ let id = pipe_connection. id ( ) ;
523+ cns. insert (
524+ id,
525+ Connection {
526+ connection : pipe_connection,
527+ handler : Some ( handler) ,
528+ quit : quit. clone ( ) ,
529+ } ,
530+ ) ;
531+
532+ // We need to ensure that only when the connection is successfully inserted into the
533+ // connections map can the handler send fd to notify the reaper to recycle the connection.
534+ // Otherwise, the handler may have been executed and sent fd to notify the reaper to recycle
535+ // the connection, and the connection has not been inserted into the map. Then the reaper cannot
536+ // find the corresponding connection after receiving the fd, and loses the opportunity to recycle
537+ // the connection, causing fd leakage;
538+ // Notify the handler continue, to send fd to reaper thread.
539+ sync_tx. send ( ( ) ) . unwrap_or ( ( ) ) ;
540+ } )
541+ . map_err ( |e| warn ! ( "spawn handler thread failed with: {:?}" , e) ) ;
527542 } // end loop
528543
529544 // notify reaper thread to exit.
0 commit comments