[comp.windows.x] The problem of fitting your application into XtAppMainLoop.

gjc@eileen.mga.com (George J. Carrette) (09/28/89)

Design questions and requests for comments on XT application main loop
issues. I am particularly interested in hearing from X Designers about
the legality (e.g. long term usability and portability, reentrancy
considerations) of simple solution #2. 

At first glance it is very difficult if not impossible in some
applications to always return within a short time from procedures
invoked by the XtAppAddWorkProc mechanism in the XtAppMainLoop.  (And
indeed going to a WorkProc itself requires a callback to QUEUE some
work rather than to try to complete the work while inside the
callback).

Examples:
 (*) hit the RUN button on a simulator, for example an x-window interface to
     SPICE.
 (*) loading/saving or compiling a knowledge base in an expert system shell.
 (*) hit the RUN button in an expert system.
 (*) an X-window interface to Macsyma, which may compute something fast or
     very slowly.

There are four ways to deal with this:
(1) Write an interposer process. Communicate with a subprocess through
    a pipe (or vms mailbox) to do the actual work.
  Advantage: Solves the problem in a conceptually simple way.
  Disadvantages: 
   * You must use a remote-procedure-call-like mechanism. You must maintain
     both sides of an imposed protocol. You may have to spend a lot of time
     in the long run in designing this protocol and maintaining it.
   * Access to data structures such as the graphical representation of
     objects being edited, simulation statements, rules, etc, is either
     much more restricted and slow (through the pipe) or much more complex
     (through a shared-memory interlocked database) and non-portable.

(2) When you are in the XtAppAddWorkProc invoked procedure which is going to
    compute for a long time, arrange to POLL for x-events in various places
    in your code. 
  Advantage: For most simulators, expert systems, anything with a loop or
  with frequent calls to a few known routines, this is rather easy to set up.
  ??Disadvantage??: None that I can seen or experimentally determine now.

  Code fragments to give you an idea of the implementation:
  
XtCallbackProc cb_set_abort_flag(widget,tag,reason)
/* a call-back for a work-in-progress box cancel button */
{abort_on_next_poll = 1;}

void decw_events_poll()
{long want_mask;
 if (abort_on_next_poll)
   {abort_on_next_poll = 0;
    error_longjump("ABORTED",NIL);}
 want_mask = XtIMXEvent | XtIMTimer;
 if ((XtAppPending(context) & want_mask) != 0)
   XtAppProcessEvent(context,want_mask);
 if (abort_on_next_poll)
   {abort_on_next_poll = 0;
    error_logjump("ABORTED",NIL);}}

#define POLLING_HANDLER_INLINE() if(--polling_counter < 0)polling_handler()


(3) Write enough of your application in an interpreted language with
an explicit-control interpreter or threaded-code driver (e.g. MIT C-SCHEME)
such that the interpreter can run for a limited amount of time inside a 
callback or work procedure, and then suspend itself, saving its state for
processing next time through the XtAppMainLoop(context).
 Advantage: Elegant. Simple.
 Disadvantage: Technique cannot be retrofited into existing applications
 written in C, FORTRAN, or other language, without translating the code to
 Scheme, Forth, or whatever.

(4) Implement a stack-group or light-weight-process mechanism inside your
application operating-system-process context. Your XtWorkProc will run
for a certain amount time and a timer signal with interrupt it and 
suspend the process by the usual register/stack context switching.
 Advantage: Any existing application can be forcibly retrofitted using
 this technique.
 Disadvantage: Using the existing system debugger gets very complicated,
 porting can be a nightmare, and in most cases all I/O calls have to be
 encapsulated and suspended if needed. Basically you are writing and 
 maintaining your own little operating system.
 * Also, has potential reentrancy problems that could be worse than in #2.

swick@ATHENA.MIT.EDU (Ralph R. Swick) (09/28/89)

I'm not aware of any portability problems with XtAppPending, so
from that standpoint polling for events during your work procedure
is the easiest solution.

You are correct in pointing out that there are many reentrancy
problems with this technique, however.  Every part of the code,
including the application itself, has to implement data structure
locking.  Xlib already supports this and some work has been done
to investigate adding it to Xt and Xaw, but we've a long way to go.

In a single-threaded environment, we're reasonably confident that
we've addressed any reentrancy bugs in the Xt level.  That is, it
should be safe to call XtDispatchEvent from anywhere.  The same
is not necessarily true of Xaw, though I don't currently know of
any specific bugs.

peter@ficc.uu.net (Peter da Silva) (09/28/89)

In article <61@eileen.mga.com>, gjc@eileen.mga.com (George J. Carrette) writes:
> At first glance it is very difficult if not impossible in some
> applications to always return within a short time from procedures
> invoked by the XtAppAddWorkProc mechanism in the XtAppMainLoop.  (And
> indeed going to a WorkProc itself requires a callback to QUEUE some
> work rather than to try to complete the work while inside the
> callback).

Several months ago I argued that the X model of putting all the intelligence
in the application is a poor choice, because it forces you to recode an
X application into an event loop. There are window systems where the
server handles most of the dirty work. In Intuition, for instance, you
can set up a window such that any window manipulation short of a resize
request (moving windows, depth arranging, menus, and even toggle gadgets)
is handled without bothering the application. An application can safely
turn off resizing, put a sign up saying "I'm busy", and go away and do
real work.

The event-loop model is fine for programs that are essentially editors,
but it's not universally applicable. If it was, xterm would be a lot
less popular tool (:-> :-<).
-- 
Peter da Silva, *NIX support guy @ Ferranti International Controls Corporation.
Biz: peter@ficc.uu.net, +1 713 274 5180. Fun: peter@sugar.hackercorp.com. `-_-'
"That is not the Usenet tradition, but it's a solidly-entrenched            U
 delusion now." -- brian@ucsd.Edu (Brian Kantor)