@@ -49,10 +49,11 @@ type MessageReceiver = Receiver<(MessageHeader, Vec<u8>)>;
49
49
pub struct Server {
50
50
listeners : Vec < RawFd > ,
51
51
monitor_fd : ( RawFd , RawFd ) ,
52
- quit : Arc < AtomicBool > ,
52
+ listener_quit_flag : Arc < AtomicBool > ,
53
53
connections : Arc < Mutex < HashMap < RawFd , Connection > > > ,
54
54
methods : Arc < HashMap < String , Box < dyn MethodHandler + Send + Sync > > > ,
55
55
handler : Option < JoinHandle < ( ) > > ,
56
+ reaper : Option < ( Sender < i32 > , JoinHandle < ( ) > ) > ,
56
57
thread_count_default : usize ,
57
58
thread_count_min : usize ,
58
59
thread_count_max : usize ,
@@ -251,14 +252,14 @@ fn check_method_handler_threads(ts: &ThreadS) {
251
252
252
253
impl Default for Server {
253
254
fn default ( ) -> Self {
254
- let ( rfd, wfd) = pipe2 ( OFlag :: O_CLOEXEC ) . unwrap ( ) ;
255
255
Server {
256
256
listeners : Vec :: with_capacity ( 1 ) ,
257
- monitor_fd : ( rfd , wfd ) ,
258
- quit : Arc :: new ( AtomicBool :: new ( false ) ) ,
257
+ monitor_fd : ( - 1 , - 1 ) ,
258
+ listener_quit_flag : Arc :: new ( AtomicBool :: new ( false ) ) ,
259
259
connections : Arc :: new ( Mutex :: new ( HashMap :: new ( ) ) ) ,
260
260
methods : Arc :: new ( HashMap :: new ( ) ) ,
261
261
handler : None ,
262
+ reaper : None ,
262
263
thread_count_default : DEFAULT_WAIT_THREAD_COUNT_DEFAULT ,
263
264
thread_count_min : DEFAULT_WAIT_THREAD_COUNT_MIN ,
264
265
thread_count_max : DEFAULT_WAIT_THREAD_COUNT_MAX ,
@@ -315,40 +316,31 @@ impl Server {
315
316
self
316
317
}
317
318
318
- pub fn start ( & mut self ) -> Result < ( ) > {
319
- if self . thread_count_default >= self . thread_count_max {
320
- return Err ( Error :: Others (
321
- "thread_count_default should smaller than thread_count_max" . to_string ( ) ,
322
- ) ) ;
323
- }
324
- if self . thread_count_default <= self . thread_count_min {
325
- return Err ( Error :: Others (
326
- "thread_count_default should biger than thread_count_min" . to_string ( ) ,
327
- ) ) ;
328
- }
329
-
319
+ pub fn start_listener ( & mut self ) -> Result < ( ) > {
330
320
let connections = self . connections . clone ( ) ;
331
321
332
322
if self . listeners . is_empty ( ) {
333
323
return Err ( Error :: Others ( "ttrpc-rust not bind" . to_string ( ) ) ) ;
334
324
}
335
325
326
+ self . listener_quit_flag . store ( false , Ordering :: SeqCst ) ;
327
+ let ( rfd, wfd) = pipe2 ( OFlag :: O_CLOEXEC ) . unwrap ( ) ;
328
+ self . monitor_fd = ( rfd, wfd) ;
329
+
336
330
let listener = self . listeners [ 0 ] ;
337
331
338
332
let methods = self . methods . clone ( ) ;
339
333
let default = self . thread_count_default ;
340
334
let min = self . thread_count_min ;
341
335
let max = self . thread_count_max ;
342
- let service_quit = self . quit . clone ( ) ;
336
+ let listener_quit_flag = self . listener_quit_flag . clone ( ) ;
343
337
let monitor_fd = self . monitor_fd . 0 ;
344
338
345
- let handler = thread:: Builder :: new ( )
346
- . name ( "listener_loop" . into ( ) )
347
- . spawn ( move || {
348
- let ( reaper_tx, reaper_rx) = channel ( ) ;
339
+ let reaper_tx = match self . reaper . take ( ) {
340
+ None => {
349
341
let reaper_connections = connections. clone ( ) ;
350
-
351
- let reaper = thread:: Builder :: new ( )
342
+ let ( reaper_tx , reaper_rx ) = channel ( ) ;
343
+ let reaper_handler = thread:: Builder :: new ( )
352
344
. name ( "reaper" . into ( ) )
353
345
. spawn ( move || {
354
346
for fd in reaper_rx. iter ( ) {
@@ -360,11 +352,25 @@ impl Server {
360
352
cn. handler . take ( ) . map ( |handler| handler. join ( ) . unwrap ( ) )
361
353
} ) ;
362
354
}
355
+ info ! ( "reaper thread exited" ) ;
363
356
} )
364
357
. unwrap ( ) ;
358
+ self . reaper = Some ( ( reaper_tx. clone ( ) , reaper_handler) ) ;
359
+ reaper_tx
360
+ }
361
+ Some ( r) => {
362
+ let reaper_tx = r. 0 . clone ( ) ;
363
+ self . reaper = Some ( r) ;
364
+ reaper_tx
365
+ }
366
+ } ;
365
367
368
+ let handler = thread:: Builder :: new ( )
369
+ . name ( "listener_loop" . into ( ) )
370
+ . spawn ( move || {
366
371
loop {
367
- if service_quit. load ( Ordering :: SeqCst ) {
372
+ if listener_quit_flag. load ( Ordering :: SeqCst ) {
373
+ info ! ( "listener shutdown for quit flag" ) ;
368
374
break ;
369
375
}
370
376
@@ -384,6 +390,7 @@ impl Server {
384
390
if e == nix:: Error :: from ( nix:: errno:: Errno :: EINTR ) {
385
391
continue ;
386
392
} else {
393
+ error ! ( "failed to select error {:?}" , e) ;
387
394
break ;
388
395
}
389
396
}
@@ -393,15 +400,18 @@ impl Server {
393
400
continue ;
394
401
}
395
402
396
- if service_quit. load ( Ordering :: SeqCst ) {
403
+ if listener_quit_flag. load ( Ordering :: SeqCst ) {
404
+ info ! ( "listener shutdown for quit flag" ) ;
397
405
break ;
398
406
}
399
407
400
408
let fd = match accept4 ( listener, SockFlag :: SOCK_CLOEXEC ) {
401
409
Ok ( fd) => fd,
402
- Err ( _e) => break ,
410
+ Err ( e) => {
411
+ error ! ( "failed to accept error {:?}" , e) ;
412
+ break ;
413
+ }
403
414
} ;
404
-
405
415
let methods = methods. clone ( ) ;
406
416
let quit = Arc :: new ( AtomicBool :: new ( false ) ) ;
407
417
let child_quit = quit. clone ( ) ;
@@ -418,7 +428,7 @@ impl Server {
418
428
for r in res_rx. iter ( ) {
419
429
trace ! ( "response thread get {:?}" , r) ;
420
430
if let Err ( e) = write_message ( fd, r. 0 , r. 1 ) {
421
- info ! ( "write_message got {:?}" , e) ;
431
+ error ! ( "write_message got {:?}" , e) ;
422
432
quit_res. store ( true , Ordering :: SeqCst ) ;
423
433
break ;
424
434
}
@@ -449,7 +459,6 @@ impl Server {
449
459
break ;
450
460
}
451
461
}
452
-
453
462
// drop the res_tx, thus the res_rx would get terminated notification.
454
463
drop ( res_tx) ;
455
464
handler. join ( ) . unwrap_or ( ( ) ) ;
@@ -473,38 +482,68 @@ impl Server {
473
482
474
483
// notify reaper thread to exit.
475
484
drop ( reaper_tx) ;
476
- reaper. join ( ) . unwrap ( ) ;
477
- info ! ( "ttrpc server stopped" ) ;
485
+ info ! ( "ttrpc server listener stopped" ) ;
478
486
} )
479
487
. unwrap ( ) ;
480
488
481
489
self . handler = Some ( handler) ;
482
-
490
+ info ! ( "server listen started" ) ;
483
491
Ok ( ( ) )
484
492
}
485
493
486
- pub fn shutdown ( mut self ) {
487
- let connections = self . connections . lock ( ) . unwrap ( ) ;
494
+ pub fn start ( & mut self ) -> Result < ( ) > {
495
+ if self . thread_count_default >= self . thread_count_max {
496
+ return Err ( Error :: Others (
497
+ "thread_count_default should smaller than thread_count_max" . to_string ( ) ,
498
+ ) ) ;
499
+ }
500
+ if self . thread_count_default <= self . thread_count_min {
501
+ return Err ( Error :: Others (
502
+ "thread_count_default should biger than thread_count_min" . to_string ( ) ,
503
+ ) ) ;
504
+ }
505
+ self . start_listener ( ) ?;
506
+ info ! ( "server started" ) ;
507
+ Ok ( ( ) )
508
+ }
488
509
489
- self . quit . store ( true , Ordering :: SeqCst ) ;
510
+ pub fn shutdown_listen ( mut self ) -> Self {
511
+ self . listener_quit_flag . store ( true , Ordering :: SeqCst ) ;
490
512
close ( self . monitor_fd . 1 ) . unwrap_or_else ( |e| {
491
513
warn ! (
492
514
"failed to close notify fd: {} with error: {}" ,
493
515
self . monitor_fd. 1 , e
494
516
)
495
517
} ) ;
518
+ info ! ( "close monitor" ) ;
519
+ if let Some ( handler) = self . handler . take ( ) {
520
+ handler. join ( ) . unwrap ( ) ;
521
+ }
522
+ info ! ( "listener thread stopped" ) ;
523
+ self
524
+ }
525
+
526
+ pub fn shutdown_connection ( mut self ) {
527
+ info ! ( "begin to shutdown connection" ) ;
528
+ let connections = self . connections . lock ( ) . unwrap ( ) ;
496
529
497
530
for ( _fd, c) in connections. iter ( ) {
498
531
c. close ( ) ;
499
532
}
500
-
501
533
// release connections's lock, since the following handler.join()
502
534
// would wait on the other thread's exit in which would take the lock.
503
535
drop ( connections) ;
536
+ info ! ( "connections closed" ) ;
504
537
505
- if let Some ( handler) = self . handler . take ( ) {
506
- handler. join ( ) . unwrap ( ) ;
538
+ if let Some ( r) = self . reaper . take ( ) {
539
+ drop ( r. 0 ) ;
540
+ r. 1 . join ( ) . unwrap ( ) ;
507
541
}
542
+ info ! ( "reaper thread stopped" ) ;
543
+ }
544
+
545
+ pub fn shutdown ( self ) {
546
+ self . shutdown_listen ( ) . shutdown_connection ( ) ;
508
547
}
509
548
}
510
549
0 commit comments