"Fernando P. Schapachnik" wrote:
>         I'm trying to do Async I/O using O_ASYNC on sockets and handling
> SIGIO. My testing shows that even if I unblock SIGIO at the begining of the
> handler the kernel only delivers one level of nested signals. Ie: while the
> first SIGIO is being handled a second might arrive, but a third delivered
> signal does not reach the process.

Yes.  Signals are persistant conditions, not events.

>         The same happens if I catch the signals with sigaction and specify
> SA_NODEFER. Same program on Linux can handle up to 23 nested signals.

Depending on Linux's behaviour, which is contrary to conformance
to the POSIX standard, will make your code non-portable.


>         Is this a known behavior?

Yes.  Even better, it's standard.

> Is there any way to change it?

When you get the first SIGIO, set a flag (volatile) in the
signal handler.  In your main loop, check for the flag, and
if it is present, use poll/select to verify that there is
data pending, and while there is data pending, retrieve it.

At most, you will recheck one extra time for a run of N
events (N+1 times), and since you are concerned about
N >= 23, this overhead is practically non-existant.

If you want to avoid the "extra" system call, then switch
to using non-blocking I/O, and when the number of bytes
processed by the call is 0, then you are done with that
iteration.


This approach is portable between all versions of UNIX that
support select or poll (you can conditionally compile the
code based on the presence or absences of FD_SET_SIZE, or
other manifest constants associated solely with the poll or
select system calls, so the resulting code will be 100%
portable source code).


See also the source for the "init" program, which has to
be able to reap child processes, and so has to do SIGCHLD
or SIGCLD (depending on your flavor of UNIX) handling the
same way.

-- Terry

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message

Reply via email to