coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: timeout: heads up: kFreeBSD's timers cause all timeout tests to hang


From: Pádraig Brady
Subject: Re: timeout: heads up: kFreeBSD's timers cause all timeout tests to hang
Date: Tue, 20 Sep 2011 09:47:27 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:6.0) Gecko/20110816 Thunderbird/6.0

On 09/19/2011 12:48 PM, Jim Meyering wrote:
> While working around the getcwd limitation on kFreeBSD,
> I noticed that all timeout-using tests were hanging.
> HAVE_TIMER_SETTIME was defined, so I confirmed that
> disabling that definition made it so all tests now pass:
> 
> diff --git a/src/timeout.c b/src/timeout.c
> index d734e4e..c87d603 100644
> --- a/src/timeout.c
> +++ b/src/timeout.c
> @@ -112,7 +112,7 @@ settimeout (double duration)
>     deprecated by POSIX.  Instead we fallback to single second
>     resolution provided by alarm().  */
> 
> -#if HAVE_TIMER_SETTIME
> +#if 0
>    struct timespec ts = dtotimespec (duration);
>    struct itimerspec its = { {0, 0}, ts };
>    timer_t timerid;
> 
> Obviously the above is just FYI.
> The real change should probably be in configure-time code that tests
> not just for existence, but also for working timer functions.

It's not that simple unfortunately.
What's happening there is that glibc is emulating
these timer functions using an implicitly created thread
(on any non Linux >= 2.6 kernel).

So when timeout::cleanup() gets the SIGALRM
and then does kill(0, SIGTERM), _two_ signals
are sent, which causes it to go into a loop
sending signals.  (So do a `killall -9 timeout`
on any kfreebsd systems you experienced the hang on.)

Interestingly FreeBSD 8.2 has these timer functions
implemented in the kernel, so perhaps GNU/kFreeBSD debian 8.1
just needs better wiring up with glibc?

In any case we should handle this, but I'm unsure how to proceed.
This would work around it:

diff --git a/src/timeout.c b/src/timeout.c
index d734e4e..de7faad 100644
--- a/src/timeout.c
+++ b/src/timeout.c
@@ -146,6 +146,7 @@ settimeout (double duration)
 static int
 send_sig (int where, int sig)
 {
+  signal (sig, SIG_IGN);
   sigs_to_ignore[sig] = 1;
   return kill (where, sig);
 }

But I'm worried about blocking signals we send indefinitely,
so I think we'll need another approach.

cheers,
Pádraig.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]