Subject: Re: [bug#30950] [PATCH shepherd]: Update required guile version, and remove some hacks

From: [email-masked] (Ludovic Courtès)
Date: Fri, 06 Apr 2018 11:31:14 +0200

Hi Carlo,

Carlo Zancanaro <[email-masked]> skribis:

> On Thu, Mar 29 2018, Ludovic Courtès wrote:
>>> * modules/shepherd.scm (main): Remove SIGALRM hack for guile <=
>>> 2.0.9.
>>>
>>> ...
>>
>> Unfortunately I think the problem remains.  That’s one of the
>> reasons for using signalfd(2).
>
> I must not understand this problem. Can you explain what the problem
> is, and how this solves it? Reading the linked email didn't help me to
> understand. I've read a number of other things about Guile and how it
> handles signals and they haven't helped me to understand, either.

It’s a limitation/bug in how Guile handles signals.  Scheme signal
handlers are added to a queue of “system asyncs” (info "(guile)
Asyncs").  As the name implies, those asyncs get executed
asynchronously; this is what the ‘handle-interrupts’ instructions that
we see here are for:

--8<---------------cut here---------------start------------->8---
scheme@(guile-user)> ,compile (lambda (x) (+ 1 x))
Disassembly of <unnamed function> at #xe8:

   0    (assert-nargs-ee/locals 1 1)    ;; 2 slots (0 args)   at (unknown file):139:9
   1    (make-non-immediate 0 39)       ;; #<procedure 12fea68 at <unknown port>:139:9 (x)>
   3    (handle-interrupts)             
   4    (return-values 2)               ;; 1 value

Disassembly of <unnamed function> at #xfc:

   0    (assert-nargs-ee/locals 2 0)    ;; 2 slots (1 arg)    at (unknown file):139:9
   1    (add/immediate 0 0 1)                                 at (unknown file):139:21
   2    (handle-interrupts)             
   3    (return-values 2)               ;; 1 value

Disassembly of <unnamed function> at #x10c:

   0    (assert-nargs-ee/locals 1 1)    ;; 2 slots (0 args)   at (unknown file):139:21
   1    (static-patch! 32 -5)           
   4    (make-short-immediate 0 2052)   ;; #<unspecified>
   5    (return-values 2)               ;; 1 value
--8<---------------cut here---------------end--------------->8---

The problem is that if you have a loop around the ‘select’ syscall, you
could have a situation like this:

  1. You receive SIGCHLD; an async is queued by the C signal handler in
     libguile, and select(2) exits with EINTR.

  2. The Scheme code that called the ‘select’ procedure runs and loops
     back to the ‘select’ call.

  3. We’re now back in select(2) but we haven’t executed our signal
     handler (async), and we know it won’t run until we’ve returned from
     select(2), which could be hours away.

That’s roughly the story.  I would need to “page it in” again to think
about what can be done.

>> Can you create an account on Savannah so I can add you to the group
>> and let you push the first two patches?  :-)
>
> I have an activated account, finally! I'm czan there.

Awesome, you’re a member now, you can unleash your hacking power.  :-)

Cheers,
Ludo’.