Under UNIX operating systems, the delivery of signals such as SIGALRM (used to manage timers) can cause system calls to be interrupted. In such cases, the system call returns a status of -1 and the global errno variable is set to the value EINTR. It is the caller’s responsibility to check for this result and restart the system call when it occurs.

It is easy enough to handle this case when you make system calls directly, but sometimes the problem surfaces in libraries (even those provided by the system, such as libc) that are not properly coded against this possibility because the author assumed that no interrupts would occur. There is very little that the end user can do about such libraries except take steps that prevent signals from being raised during these critical sections.

If the IDL timer module is being used to deliver asynchronous events, it is inevitable that the delivery of SIGALRM will interfere with this sort of library code. The IDL_TimerBlock() function is available under UNIX to suspend the delivery of the timer signal. This can be used to provide a window in which no timer will fire. This routine should always be called in pairs, so the timer doesn’t get turned off permanently. It is important to be sure a longjmp() (such as caused by calling IDL_Message() with the IDL_MSG_LONGJMP action code) doesn’t happen in the critical region. In addition, this function is not re-entrant.

The effect of blocking timer delivery is that the UNIX SIGALRM signal is masked to prevent delivery. If the timer fires during this window of time, the signal will not be delivered until timers are unblocked. At that time, the timer module resumes managing the single real UNIX timer. In the meantime, timer requests are arbitrarily delayed from being queued and processed.

Excessive blocking of the timer can lead to poor timer performance and should only be performed when necessary and on the smallest possible critical section of code. Blocking and unblocking signals requires a context switch into the UNIX kernel and back, making them relatively computationally expensive operations. It is therefore better to block a longer section of code rather than block and unblock around every critical library call.

Some UNIX platforms have more problem with this issue than others. Let experience guide you in deciding when to block signals and when to let them go.

void IDL_TimerBlock(stop)

where:

stop

TRUE if the timer should be suspended, FALSE to restart it.