mtr_timer.pl
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:3k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. # -*- cperl -*-
  2. # This is a library file used by the Perl version of mysql-test-run,
  3. # and is part of the translation of the Bourne shell script with the
  4. # same name.
  5. use Carp qw(cluck);
  6. use Socket;
  7. use Errno;
  8. use strict;
  9. #use POSIX ":sys_wait_h";
  10. use POSIX 'WNOHANG';
  11. sub mtr_init_timers ();
  12. sub mtr_timer_start($$$);
  13. sub mtr_timer_stop($$);
  14. sub mtr_timer_stop_all($);
  15. sub mtr_timer_waitpid($$$);
  16. ##############################################################################
  17. #
  18. #  Initiate a structure shared by all timers
  19. #
  20. ##############################################################################
  21. sub mtr_init_timers () {
  22.   my $timers = { timers => {}, pids => {}};
  23.   return $timers;
  24. }
  25. ##############################################################################
  26. #
  27. #  Start, stop and poll a timer
  28. #
  29. #  As alarm() isn't portable to Windows, we use separate processes to
  30. #  implement timers. That is why there is a mtr_timer_waitpid(), as this
  31. #  is where we catch a timeout.
  32. #
  33. ##############################################################################
  34. sub mtr_timer_start($$$) {
  35.   my ($timers,$name,$duration)= @_;
  36.   if ( exists $timers->{'timers'}->{$name} )
  37.   {
  38.     # We have an old running timer, kill it
  39.     mtr_timer_stop($timers,$name);
  40.   }
  41.  FORK:
  42.   {
  43.     my $tpid= fork();
  44.     if ( ! defined $tpid )
  45.     {
  46.       if ( $! == $!{EAGAIN} )           # See "perldoc Errno"
  47.       {
  48.         mtr_debug("Got EAGAIN from fork(), sleep 1 second and redo");
  49.         sleep(1);
  50.         redo FORK;
  51.       }
  52.       else
  53.       {
  54.         mtr_error("can't fork");
  55.       }
  56.     }
  57.     if ( $tpid )
  58.     {
  59.       # Parent, record the information
  60.       $timers->{'timers'}->{$name}->{'pid'}= $tpid;
  61.       $timers->{'timers'}->{$name}->{'duration'}= $duration;
  62.       $timers->{'pids'}->{$tpid}= $name;
  63.     }
  64.     else
  65.     {
  66.       # Child, redirect output and exec
  67.       # FIXME do we need to redirect streams?
  68.       $0= "mtr_timer(timers,$name,$duration)";
  69.       sleep($duration);
  70.       exit(0);
  71.     }
  72.   }
  73. }
  74. sub mtr_timer_stop ($$) {
  75.   my ($timers,$name)= @_;
  76.   if ( exists $timers->{'timers'}->{$name} )
  77.   {
  78.     my $tpid= $timers->{'timers'}->{$name}->{'pid'};
  79.     # FIXME as Cygwin reuses pids fast, maybe check that is
  80.     # the expected process somehow?!
  81.     kill(9, $tpid);
  82.     # As the timers are so simple programs, we trust them to terminate,
  83.     # and use blocking wait for it. We wait just to avoid a zombie.
  84.     waitpid($tpid,0);
  85.     delete $timers->{'timers'}->{$name}; # Remove the timer information
  86.     delete $timers->{'pids'}->{$tpid};   # and PID reference
  87.     return 1;
  88.   }
  89.   else
  90.   {
  91.     mtr_debug("Asked to stop timer "$name" not started");
  92.     return 0;
  93.   }
  94. }
  95. sub mtr_timer_stop_all ($) {
  96.   my $timers= shift;
  97.   foreach my $name ( keys %{$timers->{'timers'}} )
  98.   {
  99.     mtr_timer_stop($timers, $name);
  100.   }
  101.   return 1;
  102. }
  103. sub mtr_timer_timeout ($$) {
  104.   my ($timers,$pid)= @_;
  105.   return "" unless exists $timers->{'pids'}->{$pid};
  106.   # We got a timeout
  107.   my $name= $timers->{'pids'}->{$pid};
  108.   mtr_timer_stop($timers, $timers->{'timers'}->{$name});
  109.   return $name;
  110. }
  111. 1;