[Top][All Lists]

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

[Chicken-users] Fwd: Re: process-wait

From: Jörg F . Wittenberger
Subject: [Chicken-users] Fwd: Re: process-wait
Date: 02 Sep 2011 18:22:56 +0200

Hi all,

I accidentally did not sent my last reply to the list.
But it seems outdated now anyway: I gave it a shot.
And it appears to work -- almost.  Or for a while that is.  See 1 below.

In fact it runs for a while and has no problems to run (gc #t)
in each and every signal handler.

However there are problems, which need to be resolved.

1. The change apparently mitigates the issue (that's my unproven hypothesis)
but does not solve it: execution of the signal handler is delayed until
after the garbage collector is done instead of running it right before.
(Or at least that's what I tried to do.) But doing so requires (me so far) to change the continuation (slot 1)
of the current-thread, which requires a minimum amount of heap space
...which might be not available as Kon pointed out.
(And eventually it still loops, just less often.)

1b. I'm positive that there could be a C level hack (I feel unable to write
by now) make sure there is so much space.  It's exactly on lambda.

2. I'm hopelessly unsure how to hook this in properly.

  So far I changed the ##sys#interrupt like this:

(define (##sys#async-interrupt-hook next) #f)

(define (##sys#interrupt-hook reason state)
 (cond ((fx> (##sys#slot ##sys#pending-finalizers 0) 0)
         (##sys#run-pending-finalizers state) )
         (let ((ct ##sys#current-thread))
           (##sys#setslot ct 1 (let ((cont (##sys#slot ct 1)))
                                 (lambda () (##sys#async-interrupt-hook) 
(cont)))) )
         (##sys#context-switch state))
        (else (##sys#context-switch state) ) ) )

  IMHO we should at least use the idea of a separate signal handling
  thread as I pointed out below.

3. It might be all much easier to rearrange cicken different way to
  allow "real" code in signal handlers.  (mutex-unlock! is already
  proven to be "real code" in that case, i.e., *will* hang eventually.)

4. I'd like to depreciate ##sys#signals-peek right from the begin.
  (In so far the code needs some clean up.)

Nevertheless take it as a first shot.  Or as inspiration.

---------- Forwarded message ----------
date: 02 Sep 2011 11:37:56 +0200
from: "Jörg F. Wittenberger" <address@hidden>
subject: Re: [Chicken-users] process-wait
to: Kon Lovett <address@hidden>

On Sep 1 2011, Kon Lovett wrote:

Hi Jörg,

Probably of no use to you but … When I added all the extra unix (Chicken v2 I think) signals stuff I figured (ha) that a Scheme signal handler could only perform operations that accessed existing structures, no heap mutation. I used handlers that basically only set flags.

Thanks, this is very useful information to me: it confirms my suspicion,
hence I can save the time to investigate deeper.

We hope but do nothing to ensure:

- there is suffcient stack/nursery to invoke & execute the handler w/o a gc - the handler can execute in the current thread context w/o stepping on anything

Now this is a *serious* limitation on the code a signal handler may
contain.  This ought to go into the docs.  At least.

Next let's think what can be done about that.

The first think which comes to mind would be an extra thread to actually
execute the interrupt handlers code and a preallocated (maybe even in static
C) to hold pending signals.

I think of an array of _NSIG (linux) integers, each counting
the number of occurrences of that signal not handled so far.

(However I'm unsure: if we could live with signals received while the
same signal being handled getting lost, the code would be simpler.)

Any better idea out there?


On Sep 1, 2011, at 12:37 PM, Jörg F. Wittenberger wrote:

Hi Mario,

reproducing on *vanilla* 4.7.2 would be a challenge.
I need to mention that I'm still running from a modified scheduler
(uses llrb-trees instead of linear lists and some more fixes,
which have not yet made it into chicken core - probably since
I'm using a procedural macro expansion which is now even decpreciated).

However I just have been able to pin things down even more.
I removed all my changes so far.  Back to code which has been working
literally for years now.  Then I added this simple signal handler:

(define (process-signal/chld signum) (gc #t))

(set-signal-handler! signal/chld process-signal/chld)

Voila!  It hang, hung and hung.

(Only kill -9 would harm it, something I've not seen before too often.)

Changing (gc #t) for (gc #f) made the difference that it would hang
sometimes, as before when running all the other code.

On Sep 1 2011, Mario Domenech Goulart wrote:

Hi Jörg,

On 01 Sep 2011 19:55:17 +0200 Jörg F. Wittenberger <address@hidden> wrote:

On Sep 1 2011, address@hidden wrote:

Hope I haven't missed something you were getting at.

Not exactly.  But at this time my bet is different issue.
My hypothesis is that there's a garbage collection triggered
within the signal handler and this interferes with stack layout
or the other way around, the signal handler is run during gc.

I mean: why the hell does it work most of the time, even sustains
a killall to 50 subprocesses often enough and sometimes
just ends up looping.  (with gdb I found it in C_reclaim - no
surprise, but then it should continue at a point with the next
trace message, shouldn't it?)

Can you reproduce this behavior with 4.7.2 too? Just a wild guess, but I
wonder if the problem you are facing is something related to #668

Best wishes.

Chicken-users mailing list

Attachment: asyncsignals.diff
Description: asyncsignals.diff

reply via email to

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