Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 11 Mar 1997 21:50:52 +1100
From:      Bruce Evans <bde@zeta.org.au>
To:        ache@nagual.ru, brian@awfulhak.demon.co.uk
Cc:        brian@utell.co.uk, current@FreeBSD.org
Subject:   Re: ppp
Message-ID:  <199703111050.VAA09291@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>> Ok, so if I put (a fixed) sig.c back in there, could I ask you to do
>> some testing ?  I was thinking of:
>> 
>> void handle_signals() {
>>     int sig;
>>     int had;
>> 
>>     had = caused;
>>     if (had)
>>        for (sig=0; sig<__MAXSIG; sig++)
>>            if (had&(1<<sig)) {
>>                caused &= ~(1<<sig);
>>                (*handler[sig])(sig+1);
>>            }
>> }
>
>This way you lost _number_ of signals which may come. Since all signals
>mapped to single bit in "caused" bitmask, here can be f.e. 10 or more
>similar signals, but only one time signal handler will be executed. You
>need to replace "caused" bitmask with "int caused[__MAXSIG];" and count
>true number of signals come: caused[sig]++ (decrease it when handler was
>executed: caused[sig]--).

Generally you don't care and can't tell exactly how many signals occurred
(the system doesn't count them).  One exception might be if SIGALRM is
pended and there is too large a latrency before unpending.  Then counting
could be used to tell how many SIGALRMs were mishandled :-).

The main problems here are:
1. the code is non-portable.  sigset_t might be larger than int, and not
   using sigset_t makes it hard to use sigprocmask().
2. `caused &= ~(1<<sig);' might not be atomic.  All signals should be
   blocked when `caused' is changed.
3. Some signals should probably be blocked when the handler is called.
   See Andrey's old mail.
4. Perhaps there should a loop to handle signals that arrive after `had'
   is initialized.  This depends on how long you can afford to wait
   before the next call to handle signals.  Some locking may be required.

>BTW, why you use own __MAXSIG when standard
>NSIG is available from signal.h? 

NSIG is nonstandard.  The only standard way to tell how many signals there
are is to call sigisvalid() for all reasonable signal numbers, attempting
to avoid bugs in sigisvalid() (see cvs/lib/sighandle.c).  For a general
signal catcher you can just use the maximum of all the signal numbers that
you are catching.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199703111050.VAA09291>