summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjorn Munch <Bjorn.Munch@sun.com>2009-11-24 09:12:48 +0100
committerBjorn Munch <Bjorn.Munch@sun.com>2009-11-24 09:12:48 +0100
commite1fbb32e76d11c743fd6852e976a7c1451c5a2fe (patch)
treeaa1d1588126112c63e05828eb137ab1909fb7c14
parenta9fd7242b569ed91893a5c9fcd75ceefc638ca6e (diff)
downloadmariadb-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.pm91
-rw-r--r--mysql-test/lib/mtr_misc.pl13
-rwxr-xr-xmysql-test/mysql-test-run.pl79
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;
}