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