chicken-hackers
[Top][All Lists]
Advanced

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

Re: [Chicken-hackers] [PATCH] Fix for #989 and hopefully #877 too


From: Jörg F. Wittenberger
Subject: Re: [Chicken-hackers] [PATCH] Fix for #989 and hopefully #877 too
Date: Wed, 06 Nov 2013 15:21:18 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130329 Thunderbird/17.0.5

Am 06.11.2013 15:09, schrieb John Cowan:
Peter Bex scripsit:

As far as I know, this issue was never "introduced" to CHICKEN, but was
always there.  In earlier versions, only one signal could be handled at
a time.  Felix added the backlog of pending signals in order to avoid
dropping (too many) signals while handling other signals.
If people are trying to use signals for reliable IPC,
they are beating the air.  Whatever may be the case for
particular kernels, the Single Unix Standard says at
<http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html>:

     If a subsequent occurrence of a pending signal is generated, it
     is implementation-defined as to whether the signal is delivered
     or accepted more than once in circumstances other than those in
     which queuing is required.

Those circumstances turn out to be RT signal delivery, which I assume
is not the issue here, or ones explicitly sent with sigqueue().


Thanks for pointing this out.

For me the problem with the overflowing signal queue was in fact that too many signals of one type (signum) will cause drops of *other* signals. That's been bad for me.

My solution at that time was to coalesce signals by type and handle all reasons of a particular signal in a single signal handler (anyway) since - as you're pointing out - this must be done in any case.

That's why it's actually enough to have a single int "signal_pending" accumulate the signals in the "global_signal_handler" like this:

  signal_pending |= 1 << signum;


fetch them into the Scheme level and clean the buffer at once like this:

int C_signals_pending()
{
  int n = signal_pending;
  signal_pending = 0;
  return n;
}

and deliver from library.scm like this

(define ##sys#signals-pending (foreign-lambda int "C_signals_pending"))

(define (##sys#handle-signals pending handler)
  (let retry ((pending pending))
    (if (fx> pending 0)
    (begin
      (let loop ((pending pending) (reason 0))
        (let* ((p (fx/ pending 2))
           (u (fx- pending (fx* p 2))))
          (if (fx= u 1) (handler reason))
          (if (fx> u 1) (loop u p))
          (if (fx> p 0) (loop p (fx+ reason 1)))))
      (retry (##sys#signals-pending))))))





reply via email to

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