[comp.windows.x] Unix Signals and Xlib

fred@athsys.uucp (Fred Cox) (09/22/88)

We have an application that includes a real time simulator that needs
timer events, and also does things that can take a while during which
we can't conveniently process X events.

There are two things that we are doing to solve these problems that mix
signals and X.  One is to process X events while something is running
that takes a long time, such as calling "system()".  The other is
regular timer events to have the simulator run in real time.

Our faulty solution to the first problem sets a timer to run, and
checks X for the next Exposure event, and processes it.

The second problem involves setting the timer, and sending a
ClientMessage back to our own process, so that we can use XNextEvent.

Apparently our solutions cause big problems, though.  We get lots
of errors like: "sequence lost!", and "XError( 1): <bad request code>
XID(000000), Serial(1964/2101) Minor(  0) Major(0)".

All the signals that we use are SIGALRM, so that we can have things
that happen in something approaching real time.  We have cases in which
an XCheckIfEvent is called at signal level, and also in which drawing
commands and ClientMessages are sent from signal level.

There seems to be a pair of macros called LockDisplay and UnlockDisplay,
but these are not implemented in the Sun 3 version.  Would these help
if they were implemented?  Has anyone implemented them?

Can anyone suggest another scheme that will get around these problems?

------------------------
Fred Cox, reachable at: sun!athsys!fred

jim@EXPO.LCS.MIT.EDU (Jim Fulton) (09/22/88)

If you are making calls to Xlib from inside a signal handler, you'll need to
make sure that you are interlocked with any other calls.  You could do this by
implementing the LockDisplay/UnlockDisplay (which are geared more towards
multiprocessor systems than what you are looking to do) calls in your Xlib, but
that would restrict you to using your own Xlib, reducing portability. 

Instead, if you can isolate all of your Xlib calls, you can stick a semaphore
around them that your signal handler can check to see whether or not it should
attempt any X stuff.  You still might run into problems if your machine can't
set the semaphore atomically (in which case you might want to block
interrupts).  If you are lucky, you might be able to structure things so that
the interrupt handler can simply put some sort of "job" onto a work queue that
will get processed as soon as whatever is doing the current Xlib calls
finishes. 

						Jim Fulton
						MIT X Consortium

dheller@cory.Berkeley.EDU (Dan Heller) (09/24/88)

In article <148@poseidon.UUCP> fred%athsys.uucp@sun.com (Fred Cox) writes:
>We have an application that includes a real time simulator that needs
>timer events, and also does things that can take a while during which
>we can't conveniently process X events.

The first thing to remember is that your application doesn't run
synchronously with the server.  A very common mistake to make when
writing programs that deal with SIGALARMs, is that you are likely to
interrupt a communication with the server and will probably send an
incorrect packet across the wire.  The more you timeout, the more
likely this is going to happen.

Of course, this is very application dependent.  I learned my lesson
with my X version of qix -- a simulation of a video game.  This thing
wants to timeout every 40000-usecs to move the objects on the screen,
but it interrupts user interaction (events).  I eventually took out
the timeouts altogether and ended up doing something like:
    loop {
	if (XPending()) {
	    XNextEvent();
	    process_event();
	}
	do_stuff_or_continue_with_stuff();
    }

However, since writing that code, I've found the best way to handle
timeouts (to a surprisingly fine granularity) is to use the toolkit
timeout functions.  XtAddTimeOut() etc...

>Apparently our solutions cause big problems, though.  We get lots
>of errors like: "sequence lost!", and "XError( 1): <bad request code>
>XID(000000), Serial(1964/2101) Minor(  0) Major(0)".

that's cuz you interrupted sokmething being sent to the server,
went to handle a timeout and called another Xlib call -- the pack
the server got was undoubtly full of garbage.

>Can anyone suggest another scheme that will get around these problems?
If you can't use the toolkit, then you're not going to get good IO at
all (see qix).  Otherwise, if someone else has some helpful info, I'd
like to know about it, too :-)

Dan Heller	<island!argv@sun.com>