[comp.windows.x] Don't bother using signals at all

stpeters@dawn.crd.ge.COM (Dick St.Peters) (03/10/90)

[According to syslog, I accidently sent this to xpert-request the
first time - sorry about that.]

> For instance, what if I
> had a model solver that was going to take 7 hours to run a solve on a
> model. The user clicks a SOLVE widget and its out of the event loop
> for 7 hours. During that time all kinds of events could be received

Don't bother with signals.  Use this totally different approach, which
sounds bizarre at first but works wonderfully, allowing events to be
processed normally while your long processing goes on.  It makes use
of the XView Notifier - for you Motif fans, remember you can use the
Notifier separately from the rest of XView, avoiding OpenLook.

Caveat: I've only actually implemented the following scheme under
SunView, but I believe it will work with XView.

Before starting any event loop, call pipe(2) to get the two ends of a
pipe as file descriptors.  Usually you do this to before forking to
establish a means of talking to a forked child, but we're going to use
it to talk to ourself!

Interpose an event handler using Notify_interpose_event_func(), then
start an asynchronous event loop with Notify_do_dispatch(), then enter
your main loop, which is now a loop blocking on a select(2) with one
end of the pipe in its readmask.

When an event occurs, your handler looks at it.  If it's not the SOLVE
click you've been waiting for, you call Notify_next_event_func(),
making happen whatever would normally happen.  But if it is that long-
awaited SOLVE click, just write a token byte to the other end of the
pipe and return.

Data in the pipe causes your main-loop select(2) to return; your main
loop wakes up, reads the token, discovers it's supposed to SOLVE, and
calls solve(), which goes off and solves for your 7 hours.  In the
meantime, the asynchronous event loop continues normal processing of
other X events.

You've satisfied the dictum that event handlers shouldn't do much,
events continue to get normal processing while solving, and you can
initiate solving with a click.  The solve() procedure can fork a
separate process (and possibly nice it) if you want; you could then
have a STOP button that killed the child to stop solving.

I know, I know, programs that talk to themselves are sick; I laughed
at the friend who first came up with this sort of thing for a long
time.  Then I tried it.  Sooooo many things suddenly got easier.

--
Dick St.Peters, GE Corporate R&D, Schenectady, NY
stpeters@dawn.crd.ge.com	uunet!dawn.crd.ge.com!stpeters

mouse@LARRY.MCRCIM.MCGILL.EDU (der Mouse) (03/10/90)

>> For instance, what if I had a model solver that was going to take 7
>> hours to run a solve on a model.

> Don't bother with signals.  Use this totally different approach,
> which sounds bizarre at first but works wonderfully, allowing events
> to be processed normally while your long processing goes on.  It
> makes use of the XView Notifier

Fine, provided you're willing to tie yourself to systems where all the
ugly tricks XView uses will work.

> Before starting any event loop, call pipe(2) to get the two ends of a
> pipe as file descriptors.  [...] [W]e're going to use it to talk to
> ourself!

Be very careful here.  Is it guaranteed a pipe is buffered?  I don't
think the specified semantics forbid an implementation where a write
blocks until all data have been read.

Oh yes, I forgot.  We're willing to make all sorts of system-specific
assumptions.

> The solve() procedure can fork a separate process (and possibly nice
> it) if you want; you could then have a STOP button that killed the
> child to stop solving.

If you're going to do *that*, there's no problem to begin with.

> I know, I know, programs that talk to themselves are sick;

Well, dubious at least.  You will probably get away with it just fine,
but wait for the day when you're writing that one byte too many, or
(potentially) the system is short of mbufs, and you deadlock with
yourself....

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu