GNU bug report logs - #14640
SA_RESTART prevents execution of signal handlers

Previous Next

Package: guile;

Reported by: ludovic.courtes <at> inria.fr (Ludovic Courtès)

Date: Mon, 17 Jun 2013 14:07:02 UTC

Severity: normal

Done: Andy Wingo <wingo <at> pobox.com>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 14640 in the body.
You can then email your comments to 14640 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-guile <at> gnu.org:
bug#14640; Package guile. (Mon, 17 Jun 2013 14:07:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to ludovic.courtes <at> inria.fr (Ludovic Courtès):
New bug report received and forwarded. Copy sent to bug-guile <at> gnu.org. (Mon, 17 Jun 2013 14:07:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: ludovic.courtes <at> inria.fr (Ludovic Courtès)
To: bug-guile <at> gnu.org
Subject: SA_RESTART prevents execution of signal handlers
Date: Mon, 17 Jun 2013 15:54:45 +0200
When using SA_RESTART, signal handlers are never executed, as in this
example (checked on 2.0.9+):

--8<---------------cut here---------------start------------->8---
(sigaction SIGALRM
  (lambda (signum)
    (pk 'sig signum))
  SA_RESTART)
(alarm 3)
(pk 'char (read-char))
--8<---------------cut here---------------end--------------->8---

Presumably this is because the read(2) syscall is automatically
restarted, leaving no chance for the handler async to run.

Ludo’.




Reply sent to Andy Wingo <wingo <at> pobox.com>:
You have taken responsibility. (Tue, 21 Jun 2016 06:38:02 GMT) Full text and rfc822 format available.

Notification sent to ludovic.courtes <at> inria.fr (Ludovic Courtès):
bug acknowledged by developer. (Tue, 21 Jun 2016 06:38:02 GMT) Full text and rfc822 format available.

Message #10 received at 14640-done <at> debbugs.gnu.org (full text, mbox):

From: Andy Wingo <wingo <at> pobox.com>
To: ludovic.courtes <at> inria.fr (Ludovic Courtès)
Cc: 14640-done <at> debbugs.gnu.org
Subject: Re: bug#14640: SA_RESTART prevents execution of signal handlers
Date: Tue, 21 Jun 2016 08:37:37 +0200
On Mon 17 Jun 2013 15:54, ludovic.courtes <at> inria.fr (Ludovic Courtès) writes:

> When using SA_RESTART, signal handlers are never executed, as in this
> example (checked on 2.0.9+):
>
> (sigaction SIGALRM
>   (lambda (signum)
>     (pk 'sig signum))
>   SA_RESTART)
> (alarm 3)
> (pk 'char (read-char))
>
> Presumably this is because the read(2) syscall is automatically
> restarted, leaving no chance for the handler async to run.

Thinking about this a bit -- since we always handle signals
asynchronously and have no intention of handling them synchronously,
then we just have to document this behavior.  Done in e877e1b:

  Guile handles signals asynchronously.  When it receives a signal, the
  synchronous signal handler just records the fact that a signal was
  received and sets a flag to tell the relevant Guile thread that it has a
  pending signal.  When the Guile thread checks the pending-interrupt
  flag, it will arrange to run the asynchronous part of the signal
  handler, which is the handler attached by @code{sigaction}.

  This strategy has some perhaps-unexpected interactions with the
  @code{SA_RESTART} flag, though: because the synchronous handler doesn't
  do very much, and notably it doesn't run the Guile handler, it's
  impossible to interrupt a thread stuck in a long-running system call via
  a signal handler that is installed with @code{SA_RESTART}: the
  synchronous handler just records the pending interrupt, but then the
  system call resumes and Guile doesn't have a chance to actually check
  the flag and run the asynchronous handler.  That's just how it is.

Andy




Information forwarded to bug-guile <at> gnu.org:
bug#14640; Package guile. (Tue, 21 Jun 2016 07:49:02 GMT) Full text and rfc822 format available.

Message #13 received at 14640-done <at> debbugs.gnu.org (full text, mbox):

From: ludovic.courtes <at> inria.fr (Ludovic Courtès)
To: Andy Wingo <wingo <at> pobox.com>
Cc: 14640-done <at> debbugs.gnu.org
Subject: Re: bug#14640: SA_RESTART prevents execution of signal handlers
Date: Tue, 21 Jun 2016 09:48:33 +0200
Andy Wingo <wingo <at> pobox.com> skribis:

> On Mon 17 Jun 2013 15:54, ludovic.courtes <at> inria.fr (Ludovic Courtès) writes:
>
>> When using SA_RESTART, signal handlers are never executed, as in this
>> example (checked on 2.0.9+):
>>
>> (sigaction SIGALRM
>>   (lambda (signum)
>>     (pk 'sig signum))
>>   SA_RESTART)
>> (alarm 3)
>> (pk 'char (read-char))
>>
>> Presumably this is because the read(2) syscall is automatically
>> restarted, leaving no chance for the handler async to run.
>
> Thinking about this a bit -- since we always handle signals
> asynchronously and have no intention of handling them synchronously,
> then we just have to document this behavior.  Done in e877e1b:

I think it’s problematic though.  With the current design, signal
delivery is unreliable (with or without SA_RESTART; what we observe with
SA_RESTART occurs similarly if you make a syscall right after queuing,
but not running, an async.)

The more I think about it, the more I think a different approach is
needed.  On GNU/Linux, signalfd(2) may be part of the solution.

Ludo’.




Information forwarded to bug-guile <at> gnu.org:
bug#14640; Package guile. (Tue, 21 Jun 2016 08:00:03 GMT) Full text and rfc822 format available.

Message #16 received at 14640-done <at> debbugs.gnu.org (full text, mbox):

From: Andy Wingo <wingo <at> pobox.com>
To: ludovic.courtes <at> inria.fr (Ludovic Courtès)
Cc: 14640-done <at> debbugs.gnu.org, ludo <at> gnu.org
Subject: Re: bug#14640: SA_RESTART prevents execution of signal handlers
Date: Tue, 21 Jun 2016 09:59:33 +0200
On Tue 21 Jun 2016 09:48, ludovic.courtes <at> inria.fr (Ludovic Courtès) writes:

> Andy Wingo <wingo <at> pobox.com> skribis:
>
>> On Mon 17 Jun 2013 15:54, ludovic.courtes <at> inria.fr (Ludovic Courtès) writes:
>>
>>> When using SA_RESTART, signal handlers are never executed, as in this
>>> example (checked on 2.0.9+):
>>>
>>> (sigaction SIGALRM
>>>   (lambda (signum)
>>>     (pk 'sig signum))
>>>   SA_RESTART)
>>> (alarm 3)
>>> (pk 'char (read-char))
>>>
>>> Presumably this is because the read(2) syscall is automatically
>>> restarted, leaving no chance for the handler async to run.
>>
>> Thinking about this a bit -- since we always handle signals
>> asynchronously and have no intention of handling them synchronously,
>> then we just have to document this behavior.  Done in e877e1b:
>
> I think it’s problematic though.  With the current design, signal
> delivery is unreliable (with or without SA_RESTART; what we observe with
> SA_RESTART occurs similarly if you make a syscall right after queuing,
> but not running, an async.)

Can you expect any kind of reasonable behavior with SA_RESTART?  I think
not.

> The more I think about it, the more I think a different approach is
> needed.  On GNU/Linux, signalfd(2) may be part of the solution.

We already do the equivalent of signalfd(), with our self-pipe trick.
And an fd doesn't help you if the syscall has no associated fd.  Signals
are just a problem.  I agree we can do better though :)

If you are just concerned about read and write, I think the right thing
is non-blocking fd's, and making the C read/write waiters also add the
signal FD to their poll set.  WDYT?

Andy




Information forwarded to bug-guile <at> gnu.org:
bug#14640; Package guile. (Tue, 21 Jun 2016 09:47:02 GMT) Full text and rfc822 format available.

Message #19 received at 14640-done <at> debbugs.gnu.org (full text, mbox):

From: ludo <at> gnu.org (Ludovic Courtès)
To: Andy Wingo <wingo <at> pobox.com>
Cc: 14640-done <at> debbugs.gnu.org
Subject: Re: bug#14640: SA_RESTART prevents execution of signal handlers
Date: Tue, 21 Jun 2016 11:46:37 +0200
Andy Wingo <wingo <at> pobox.com> skribis:

> On Tue 21 Jun 2016 09:48, ludovic.courtes <at> inria.fr (Ludovic Courtès) writes:
>
>> Andy Wingo <wingo <at> pobox.com> skribis:
>>
>>> On Mon 17 Jun 2013 15:54, ludovic.courtes <at> inria.fr (Ludovic Courtès) writes:
>>>
>>>> When using SA_RESTART, signal handlers are never executed, as in this
>>>> example (checked on 2.0.9+):
>>>>
>>>> (sigaction SIGALRM
>>>>   (lambda (signum)
>>>>     (pk 'sig signum))
>>>>   SA_RESTART)
>>>> (alarm 3)
>>>> (pk 'char (read-char))
>>>>
>>>> Presumably this is because the read(2) syscall is automatically
>>>> restarted, leaving no chance for the handler async to run.
>>>
>>> Thinking about this a bit -- since we always handle signals
>>> asynchronously and have no intention of handling them synchronously,
>>> then we just have to document this behavior.  Done in e877e1b:
>>
>> I think it’s problematic though.  With the current design, signal
>> delivery is unreliable (with or without SA_RESTART; what we observe with
>> SA_RESTART occurs similarly if you make a syscall right after queuing,
>> but not running, an async.)
>
> Can you expect any kind of reasonable behavior with SA_RESTART?  I think
> not.

In C it does its job: signal handlers run, and other parts of the code
don’t notice the interruption.  Here it’s useless.

>> The more I think about it, the more I think a different approach is
>> needed.  On GNU/Linux, signalfd(2) may be part of the solution.
>
> We already do the equivalent of signalfd(), with our self-pipe trick.

Hmm, I wonder if it’s really equivalent.

Also, it is internal: the Scheme level cannot explicitly “convert”
signals to FDs; all it gets is those asyncs.

> And an fd doesn't help you if the syscall has no associated fd.

But those typically don’t block.

> If you are just concerned about read and write, I think the right thing
> is non-blocking fd's, and making the C read/write waiters also add the
> signal FD to their poll set.  WDYT?

There’s also ‘select’.  In the case of the Shepherd, you’re in a
‘select’ loop, waiting for events from file descriptors *and* waiting
for SIGCHLD.  However, the SIGCHLD handler can end up running long after
the fact.  In this case, it would help to explicitly use use ‘signalfd’
at the Scheme level (whether it’s used internally in libguile doesn’t
matter.)

Not sure I follow your suggestion.  My naïve view is that one would
probably expect/want signals to behave “like in C”, meaning that
handlers would run in a timely fashion once the signal has effectively
been received by libguile.

Thanks for your feedback!

Ludo’.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Tue, 19 Jul 2016 11:24:04 GMT) Full text and rfc822 format available.

This bug report was last modified 7 years and 276 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.