ITEM: K3238L

blocking timer interupts for the connect function


Customer is writing a program that has a signal handler for
a timer interrupt.  The timer kicks off every second; Customer
has no control over this.  When ever the interrupt occurs,
it stops the current system call and runs the signal handler
procedure.  The system call that was in progress then fails
and returns with EINTR indicating that it should be run again.
The Customer is trying to do a connect to a remote host
over a SLIP line.  The first two or three are all able to
return in less than a second, but as network traffic increases,
the connect is not able to complete in a second.  Because of 
this the connect fails, and continues to fail until the 
program quits trying.  ( at some Customer preset number )
Customer needs to prevent this from happening.

How can the signal trapping be suspended?
How can the connect subroutine be made an atomic process?


The connect function can be considered a slow system call in
this case because it is possible for the connect to block
longer than the maximum time between between timer signal
interrupts.  In reality the connect function may have far
less time than this, because the function call could come
at any time between the interrupts.  The code for the
connect then, needs to be considered a critical section
of code and treated accordingly.

In order to make the connect function perform as if it 
was atomic, the Customer's program needs to block all
signals that might call it's signal handler, for the 
duration of the connect function.  Signals can be caught,
blocked, or ignored.  Assuming that Customer does not
want to loose any signals by ignoring them, the Customer
will have to tell his program to block these signals
until such time as the critical section of code has
completed.  ( I am not clear about whether AIX 3.2.5 
queues blocked, or pending, signals or simply keeps
track of the most current signal. )  In order enable
blocking of these signals the Customer must use
the following functions:  ( from signal.h )

signal          sets signal handler functions for caught signals
sigemptyset     creates an empty bit mask to catch/block signals
sigaddset       adds a signal to a set to be caught/blocked
sigprocmask     sets the process signal mask; shows state of mask
sigpending      returns list of pending signals
sigismember     tests results of sigpending for inclusion of a signal

Before entering the critical section the Customer needs to:

  1)    Generate a new mask to enable blocking of currently
        trapped signals.

                sigemptyset( &newmask );
                sigaddset( &newmask, SIGQUIT );
                        /* adds SIGQUIT to the set of signals to block */
                        /* do a signaddset for all signals to block    */

        where newmask is of type setset_t defined in signal.h

  2)    Set the new signal mask and save the old one.

                if ( sigprocmask( SIG_BLOCK, &newmask, &oldmask ) \< 0 )
                  err_sys( "SIG_BLOCK err" );

        where newmask, oldmask are type sigset_t

  3)    Run the critical section of code; i.e. call the connect
        and all associated statements that need to be atomic.

  4)    Reset the signal mask.

                if ( sigprocmask( SIG_SETMASK, &oldmask, NULL ) \< 0 )
                  err_sys( "SIG_SETMASK error" );

This should allow the Customer to run the connect operation
as if it were atomic, by blocking all normally caught signals
until the completion of the critical section.  A more thorough
explanation of signals can be found in _Advanced Programming in
the Unix Environment_ by W. Richard Stevens, which is where
most of this information was drawn from.

Support Line: blocking timer interupts for the connect function ITEM: K3238L
Dated: June 1994 Category: N/A
This HTML file was generated 99/06/24~13:30:42
Comments or suggestions? Contact us