55 lines
2.1 KiB
Diff
55 lines
2.1 KiB
Diff
|
From ecbf46993f6ffbdc255f6ded3c6c05a8266a71e8 Mon Sep 17 00:00:00 2001
|
||
|
From: David Mitchell <davem@iabyn.com>
|
||
|
Date: Tue, 7 Aug 2018 12:26:31 +0100
|
||
|
Subject: [PATCH] Time-HiRes/t/itimer.t: avoid race condition.
|
||
|
MIME-Version: 1.0
|
||
|
Content-Type: text/plain; charset=UTF-8
|
||
|
Content-Transfer-Encoding: 8bit
|
||
|
|
||
|
This test script sets a repeating interval timer going, and after 4
|
||
|
'ticks' (SIGVTALRM), disables the timer (by setting it to zero).
|
||
|
|
||
|
The main loop which does CPU burning, does a getitmer() every now and
|
||
|
again, and when the value is zero, assumes the signal handler has
|
||
|
disabled the timer, and so finishes.
|
||
|
|
||
|
The trouble was that it was checking the 'time left', which can reach
|
||
|
zero because the interval timer has counted down to zero, and the signal
|
||
|
handler is about to be called, but the interval hasn't been reset back
|
||
|
to 0.4s yet.
|
||
|
|
||
|
i.e. the code doesn't distinguish between "timer disabled" and "timer
|
||
|
just reached zero".
|
||
|
|
||
|
In that scenario, the cleanup code in the test script disables the
|
||
|
SIGVTALRM handler while the timer is still active, and so the process
|
||
|
gets killed if another signal is raised.
|
||
|
|
||
|
This commit changes the test to check the second value returned by
|
||
|
getitmer() for being zero rather than the first - the second being the
|
||
|
repeat interval, whichb is always 0.4 until the timer is disabled.
|
||
|
|
||
|
Signed-off-by: Petr Písař <ppisar@redhat.com>
|
||
|
---
|
||
|
dist/Time-HiRes/t/itimer.t | 4 +++-
|
||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/dist/Time-HiRes/t/itimer.t b/dist/Time-HiRes/t/itimer.t
|
||
|
index e196b1648c..432b224488 100644
|
||
|
--- a/dist/Time-HiRes/t/itimer.t
|
||
|
+++ b/dist/Time-HiRes/t/itimer.t
|
||
|
@@ -51,7 +51,9 @@ ok(defined $virt && abs($virt / 0.5) - 1 < $limit,
|
||
|
printf("# getitimer: %s\n", join(" ",
|
||
|
Time::HiRes::getitimer(&Time::HiRes::ITIMER_VIRTUAL)));
|
||
|
|
||
|
-while (Time::HiRes::getitimer(&Time::HiRes::ITIMER_VIRTUAL)) {
|
||
|
+# burn CPU until the VTALRM signal handler sets the repeat interval to
|
||
|
+# zero, indicating that the timer has fired 4 times.
|
||
|
+while ((Time::HiRes::getitimer(&Time::HiRes::ITIMER_VIRTUAL))[1]) {
|
||
|
my $j;
|
||
|
for (1..1000) { $j++ } # Can't be unbreakable, must test getitimer().
|
||
|
}
|
||
|
--
|
||
|
2.14.4
|
||
|
|