diff options
author | Bjorn Munch <Bjorn.Munch@sun.com> | 2009-11-24 09:12:48 +0100 |
---|---|---|
committer | Bjorn Munch <Bjorn.Munch@sun.com> | 2009-11-24 09:12:48 +0100 |
commit | e1fbb32e76d11c743fd6852e976a7c1451c5a2fe (patch) | |
tree | aa1d1588126112c63e05828eb137ab1909fb7c14 | |
parent | a9fd7242b569ed91893a5c9fcd75ceefc638ca6e (diff) | |
download | mariadb-git-e1fbb32e76d11c743fd6852e976a7c1451c5a2fe.tar.gz |
Bug #47978 timer : expired after 90 seconds
Problems occur after killing threads on Windows
Get rid of the timeout threads, implement simple timer in wait_any_timeout()
-rw-r--r-- | mysql-test/lib/My/SafeProcess.pm | 91 | ||||
-rw-r--r-- | mysql-test/lib/mtr_misc.pl | 13 | ||||
-rwxr-xr-x | mysql-test/mysql-test-run.pl | 79 |
3 files changed, 72 insertions, 111 deletions
diff --git a/mysql-test/lib/My/SafeProcess.pm b/mysql-test/lib/My/SafeProcess.pm index a620a7c6c72..bfcad910a16 100644 --- a/mysql-test/lib/My/SafeProcess.pm +++ b/mysql-test/lib/My/SafeProcess.pm @@ -188,63 +188,6 @@ sub run { } # -# Start a process that returns after "duration" seconds -# or when it's parent process does not exist anymore -# -sub timer { - my $class= shift; - my $duration= shift or croak "duration required"; - my $parent_pid= $$; - - my $pid= My::SafeProcess::Base::_safe_fork(); - if ($pid){ - # Parent - my $proc= bless - ({ - SAFE_PID => $pid, - SAFE_NAME => "timer", - PARENT => $$, - }, $class); - - # Put the new process in list of running - $running{$pid}= $proc; - return $proc; - } - - # Child, install signal handlers and sleep for "duration" - $SIG{INT}= 'IGNORE'; - - $SIG{TERM}= sub { - #print STDERR "timer $$: woken up, exiting!\n"; - exit(0); - }; - - $0= "safe_timer($duration)"; - - if (IS_WIN32PERL){ - # Just a thread in same process - sleep($duration); - print STDERR "timer $$: expired after $duration seconds\n"; - exit(0); - } - - my $count_down= $duration; - while($count_down--){ - - # Check that parent is still alive - if (kill(0, $parent_pid) == 0){ - #print STDERR "timer $$: parent gone, exiting!\n"; - exit(0); - } - - sleep(1); - } - print STDERR "timer $$: expired after $duration seconds\n"; - exit(0); -} - - -# # Shutdown process nicely, and wait for shutdown_timeout seconds # If processes hasn't shutdown, kill them hard and wait for return # @@ -542,6 +485,40 @@ sub wait_any { # +# Wait for any process to exit, or a timeout +# +# Returns a reference to the SafeProcess that +# exited or a pseudo-process with $proc->{timeout} == 1 +# + +sub wait_any_timeout { + my $class= shift; + my $timeout= shift; + my $proc; + my $millis=10; + + do { + ::mtr_milli_sleep($millis); + # Slowly increse interval up to max. 1 second + $millis++ if $millis < 1000; + # Return a "fake" process for timeout + if (::has_expired($timeout)) { + $proc= bless + ({ + SAFE_PID => 0, + SAFE_NAME => "timer", + timeout => 1, + }, $class); + } else { + $proc= check_any(); + } + } while (! $proc); + + return $proc; +} + + +# # Wait for all processes to exit # sub wait_all { diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl index 658eb270535..97eb693b52e 100644 --- a/mysql-test/lib/mtr_misc.pl +++ b/mysql-test/lib/mtr_misc.pl @@ -30,7 +30,9 @@ sub mtr_script_exists(@); sub mtr_file_exists(@); sub mtr_exe_exists(@); sub mtr_exe_maybe_exists(@); - +sub mtr_milli_sleep($); +sub start_timer($); +sub has_expired($); ############################################################################## # @@ -167,11 +169,18 @@ sub mtr_exe_exists (@) { } -sub mtr_milli_sleep { +sub mtr_milli_sleep ($) { die "usage: mtr_milli_sleep(milliseconds)" unless @_ == 1; my ($millis)= @_; select(undef, undef, undef, ($millis/1000)); } +# Simple functions to start and check timers (have to be actively polled) +# Timer can be "killed" by setting it to 0 + +sub start_timer ($) { return time + $_[0]; } + +sub has_expired ($) { return $_[0] && time gt $_[0]; } + 1; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index ae9674bbde5..2147b4ae7a7 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -439,7 +439,7 @@ sub run_test_server ($$$) { my $result; my $exe_mysqld= find_mysqld($basedir) || ""; # Used as hint to CoreDump - my $suite_timeout_proc= My::SafeProcess->timer(suite_timeout()); + my $suite_timeout= start_timer(suite_timeout()); my $s= IO::Select->new(); $s->add($server); @@ -460,7 +460,6 @@ sub run_test_server ($$$) { mtr_verbose("Child closed socket"); $s->remove($sock); if (--$childs == 0){ - $suite_timeout_proc->kill(); return $completed; } next; @@ -529,13 +528,11 @@ sub run_test_server ($$$) { if ( !$opt_force ) { # Test has failed, force is off - $suite_timeout_proc->kill(); push(@$completed, $result); return $completed; } elsif ($opt_max_test_fail > 0 and $num_failed_test >= $opt_max_test_fail) { - $suite_timeout_proc->kill(); push(@$completed, $result); mtr_report_stats("Too many failed", $completed, 1); mtr_report("Too many tests($num_failed_test) failed!", @@ -667,7 +664,7 @@ sub run_test_server ($$$) { # ---------------------------------------------------- # Check if test suite timer expired # ---------------------------------------------------- - if ( ! $suite_timeout_proc->wait_one(0) ) + if ( has_expired($suite_timeout) ) { mtr_report_stats("Timeout", $completed, 1); mtr_report("Test suite timeout! Terminating..."); @@ -2944,11 +2941,11 @@ sub check_testcase($$) # Return immediately if no check proceess was started return 0 unless ( keys %started ); - my $timeout_proc= My::SafeProcess->timer(check_timeout()); + my $timeout= start_timer(check_timeout()); while (1){ my $result; - my $proc= My::SafeProcess->wait_any(); + my $proc= My::SafeProcess->wait_any_timeout($timeout); mtr_report("Got $proc"); if ( delete $started{$proc->pid()} ) { @@ -2972,9 +2969,6 @@ sub check_testcase($$) if ( keys(%started) == 0){ # All checks completed - - $timeout_proc->kill(); - return 0; } # Wait for next process to exit @@ -3015,10 +3009,9 @@ test case was executed:\n"; } } - elsif ( $proc eq $timeout_proc ) { - $tinfo->{comment}.= "Timeout $timeout_proc for ". - "'check-testcase' expired after ".check_timeout(). - " seconds"; + elsif ( $proc->{timeout} ) { + $tinfo->{comment}.= "Timeout for 'check-testcase' expired after " + .check_timeout()." seconds"; $result= 4; } else { @@ -3033,8 +3026,6 @@ test case was executed:\n"; # Kill any check processes still running map($_->kill(), values(%started)); - $timeout_proc->kill(); - return $result; } @@ -3106,11 +3097,11 @@ sub run_on_all($$) # Return immediately if no check proceess was started return 0 unless ( keys %started ); - my $timeout_proc= My::SafeProcess->timer(check_timeout()); + my $timeout= start_timer(check_timeout()); while (1){ my $result; - my $proc= My::SafeProcess->wait_any(); + my $proc= My::SafeProcess->wait_any_timeout($timeout); mtr_report("Got $proc"); if ( delete $started{$proc->pid()} ) { @@ -3129,17 +3120,15 @@ sub run_on_all($$) if ( keys(%started) == 0){ # All completed - $timeout_proc->kill(); return 0; } # Wait for next process to exit next; } - elsif ( $proc eq $timeout_proc ) { - $tinfo->{comment}.= "Timeout $timeout_proc for '$run' ". - "expired after ". check_timeout(). - " seconds"; + elsif ($proc->{timeout}) { + $tinfo->{comment}.= "Timeout for '$run' expired after " + .check_timeout()." seconds"; } else { # Unknown process returned, most likley a crash, abort everything @@ -3151,8 +3140,6 @@ sub run_on_all($$) # Kill any check processes still running map($_->kill(), values(%started)); - $timeout_proc->kill(); - return 1; } mtr_error("INTERNAL_ERROR: run_on_all"); @@ -3382,7 +3369,7 @@ sub run_testcase ($) { } } - my $test_timeout_proc= My::SafeProcess->timer(testcase_timeout()); + my $test_timeout= start_timer(testcase_timeout()); do_before_run_mysqltest($tinfo); @@ -3390,9 +3377,6 @@ sub run_testcase ($) { # Failed to record state of server or server crashed report_failure_and_restart($tinfo); - # Stop the test case timer - $test_timeout_proc->kill(); - return 1; } @@ -3410,20 +3394,20 @@ sub run_testcase ($) { if ($proc) { mtr_verbose ("Found exited process $proc"); - # If that was the timeout, cancel waiting - if ( $proc eq $test_timeout_proc ) - { - $keep_waiting_proc = 0; - } } else { $proc = $keep_waiting_proc; + # Also check if timer has expired, if so cancel waiting + if ( has_expired($test_timeout) ) + { + $keep_waiting_proc = 0; + } } } - else + if (! $keep_waiting_proc) { - $proc= My::SafeProcess->wait_any(); + $proc= My::SafeProcess->wait_any_timeout($test_timeout); } # Will be restored if we need to keep waiting @@ -3440,9 +3424,6 @@ sub run_testcase ($) { # ---------------------------------------------------- if ($proc eq $test) { - # Stop the test case timer - $test_timeout_proc->kill(); - my $res= $test->exit_status(); if ($res == 0 and $opt_warnings and check_warnings($tinfo) ) @@ -3545,7 +3526,7 @@ sub run_testcase ($) { # ---------------------------------------------------- # Stop the test case timer # ---------------------------------------------------- - $test_timeout_proc->kill(); + $test_timeout= 0; # ---------------------------------------------------- # Check if it was a server that died @@ -3584,7 +3565,7 @@ sub run_testcase ($) { # ---------------------------------------------------- # Check if testcase timer expired # ---------------------------------------------------- - if ( $proc eq $test_timeout_proc ) + if ( $proc->{timeout} ) { my $log_file_name= $opt_vardir."/log/".$tinfo->{shortname}.".log"; $tinfo->{comment}= @@ -3825,11 +3806,11 @@ sub check_warnings ($) { # Return immediately if no check proceess was started return 0 unless ( keys %started ); - my $timeout_proc= My::SafeProcess->timer(check_timeout()); + my $timeout= start_timer(check_timeout()); while (1){ my $result= 0; - my $proc= My::SafeProcess->wait_any(); + my $proc= My::SafeProcess->wait_any_timeout($timeout); mtr_report("Got $proc"); if ( delete $started{$proc->pid()} ) { @@ -3858,9 +3839,6 @@ sub check_warnings ($) { if ( keys(%started) == 0){ # All checks completed - - $timeout_proc->kill(); - return $result; } # Wait for next process to exit @@ -3877,10 +3855,9 @@ sub check_warnings ($) { $result= 2; } } - elsif ( $proc eq $timeout_proc ) { - $tinfo->{comment}.= "Timeout $timeout_proc for ". - "'check warnings' expired after ".check_timeout(). - " seconds"; + elsif ( $proc->{timeout} ) { + $tinfo->{comment}.= "Timeout for 'check warnings' expired after " + .check_timeout()." seconds"; $result= 4; } else { @@ -3894,8 +3871,6 @@ sub check_warnings ($) { # Kill any check processes still running map($_->kill(), values(%started)); - $timeout_proc->kill(); - return $result; } |