XForms: SIGALRM handling: some insights

Paul Barton-Davis (pbd@Op.Net)
Tue, 7 Jul 1998 12:47:36 -0400

# To subscribers of the xforms list from Paul Barton-Davis <pbd@Op.Net> :

I just wanted to describe a little trick I came up in connection with
a short-interval timer and XForms.

To make my program work, I needed a fairly accurate timer (say, to
1/100sec) to interrupt my program and cause it to do whatever was
needed at that point in time.

My initial attempts just involved using setitimer() and SIGALRM, with
no particular interaction with the XForms main loop. I quickly
realized that by illegally using XForms functions in a reentrant way
(since my signal handler followed a call tree that ultimately lead to
various XForms functions), I was causing random,
predictably-unpredictable core dumps.

A little reading pointed me to fl_add_signal_callback(),
fl_signal_caught() and their friends. I used a dummy signal handler
that just called fl_signal_caught(), and an XForms signal callback that
did my timer-based stuff. Using these to handle SIGALRM 100 times a
second worked OK, and certainly got rid of the random core dumps, as I
expected it would.

However, this approach made the timer very unreliable, since it would
effectively only go off whenever the XForms main loop bothers to check
for signals. During any kind of sustained interaction with the program
(mouse clicks, mouse drags, window resizing or moving), the timer
would be noticeably erratic (this is a music application, so you can
*hear* it not going off on time).

Today, I thought of a new approach. It now seems very obvious, but to
save anyone else the embarassment of not thinking of it as soon as
they could, here it is.

Currently, I have a direct signal handler (called "directly" by the
kernel signal code thanks to signal(2)). However, it doesn't make any
XForms calls at all, except fl_signal_caught() once its done its work.
After that it goes away. There is a second function, written as a
callback for use with fl_add_signal_callback(), that does all screen
updating, etc. Once XForms takes control again after the signal
handler has returned, it sooner or later checks for "signals". At this
time, possibly significantly after the real signal was received, it
calls the callback, and the relevant screen updates occur.

No doubt this is more or less how we're supposed to use
fl_signal_caught(), but it wasn't obvious from the documentation.
This is equivalent to what has been described here for multi-threaded
applications, in that there is complete separation of the XForms-using
code and the "other stuff", but its a little novel in that there isn't
a thread as such, merely a signal handler, and the only communication
between them is fl_signal_caught().

With this arrangement in place (plus a tricky little piece of mutual
exclusion in the screen update section), I get exactly what I needed:
the stuff requiring accurate timing gets just what it needs: even
during window resizing or moves, the timer ticks off accurately and
evenly. Meanwhile, whenever things are calm on the X front again, the
screen gets correctly updated. Seems magical.

Anyway, hope this is of help to someone. The key is split your
UI-based activity out from the backend, and have the backend
asynchronously call the UI code via fl_signal_caught().

--p

--pbd

_________________________________________________
To unsubscribe, send the message "unsubscribe" to
xforms-request@bob.usuf2.usuhs.mil or see
http://bob.usuf2.usuhs.mil/mailserv/xforms.html
XForms Home Page: http://bragg.phys.uwm.edu/xforms
List Archive: http://bob.usuf2.usuhs.mil/mailserv/list-archives/