Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!samsung!zaphod.mps.ohio-state.edu!mips!apple!sun-barr!newstop!sun!turnpike!argv From: argv%turnpike@Sun.COM (Dan Heller) Newsgroups: comp.windows.x Subject: Re: Problem with Signals Message-ID: <132399@sun.Eng.Sun.COM> Date: 1 Mar 90 22:25:22 GMT References: <9002281729.AA02895@wilkins.bcm.tmc.edu> Sender: news@sun.Eng.Sun.COM Lines: 108 From: jcarson@WILKINS.BCM.TMC.EDU (Janet L. Carson) Subject: Problem with Signals I've been watching the "problem with signals" thread, and I agree with Bob Scheifler that no one has really explained clearly what the problems are. I am in the process of writing a tool which is going to be an interface to FTP, and I am including a SIGPIPE error handler to handle the "connection lost" case. Where do I need to look out for problems? Janet L. Carson internet: jcarson@bcm.tmc.edu Baylor College of Medicine uucp: {rutgers,mailrus}!bcm!jcarson The problem with signals and X is rather simple. X is asynchronous and relies on a communication between the client (application) and the server (the X server). This "protocol" is defined and implemented using Xlib. If you are putting together a packet to send over the wire to the server and a signal "interrupts" your client side application, then you have interrupted the protocol and *may* result in a protocol error with the server. You may even get a core dump. This is not guaranteed to happen, but the case becomes much more likely if your event handler attempts to make any Xlib calls (which includes many, but not all, Xt calls). Perhaps the most common case of this is the SIGALRM signal, which is delivered as a result of such things as "setitimer". Note Brian's problem below: From: envbvs@epb2.lbl.gov (Brian V. Smith) I have put patch3 to xfig2.0 on expo.lcs.mit.edu. ... Changes from patchlevel 2: o now uses XtAddTimer instead of setitimer() for blinking text cursor The reason he did this was because xfig suffered from random core dumps as a result of the timer interfering with the X protocol and attempting to "blink" the cursor by turning it off and on. As you can see, he fixed the problem by using XtAddTimeOut() to replace the use of the timer. Xt doesn't use signals to do this -- it simulates signals by simply checking the time in the main looping mechanism. Because this particular problem is solved, and because it is the most commonly utilized signal so far, many people don't perceive the fundamental problem as being that bad. However, the "fundamental problem" still exists: if you interrupt the protocol betwween the client and server, then you must be sure to return to the place in the application that was interrupted before making further attempts to communicate with the X server. Therefore, you signal handler should not display dialog boxes, make Xlib calls, or do much any anything until it is guaranteed that you are not going to interfere with a protocol exachange. So, what do you do? Well, your signal handler could be written to set a flag to note the delivery of the signal and then return so that the code being execute may continue with whatever it's doing till you know it's safe. *that* is the problem -- you never know when it's safe. And when it *is* safe, you are not in any application-specific code. There may not be any more events in the queue so that your next event handling function won't be called for quite some time. My proposed solution is to implement a routine: XtSigRet XtAddSignalHandler(signal, handler) int signal; XtSigRet (*handler)(); XtSigRet is either void or int depending on what your UNIX OS uses for signal(). When you register your signal handler for the specified signal, when the signal is delivered, *Xt* catches the signal and notes the signal context, resources, etc.. Then, when all is well with the events and protocol, etc, your handler is called. Your handler is written _exactly the same_ as it would be had you called "signal(sig, handler)" because the same parameters are passed back into the signal handler. (XtAddSignalHandler returns the previously set handler just like signal() does.) Now, you could implement this yourself via "work procs" (see XtAddWorkProc()), but the granularity isn't fine enough. That is, work procs are only called when there are no events pending. Implemented properly, the internals to Xt would check in between event delivery to event handlers. Like rws, I don't know VMS's ASTs well enough to know how this mechasnism fits in with the sceme programmatically. However, I do know that this implementation can fit in conceptually. "signal()" can be #ifdef'ed out if necessary and those systems that don't have signal() are simply unaffected since the check for nonexistent signals does nothing. That is, I envision the implementation as being: signal is delvered, Xt sets a bit in a flag indicating that the signal has been delivered. Signal number, contenxt resource usage, etc.. are saved. At appropriate time, Xt checks signal flags and see swhich signals have been delivered and calls the signal handler with appropriate parameters saved from the real signal delivery. If VMS's ASTs has similar parameters, use those, too. dan ----------------------------------------------------------- O'Reilly && Associates argv@sun.com / argv@ora.com 632 Petaluma Ave, Sebastopol, CA 95472 800-338-NUTS, in CA: 800-533-NUTS, FAX 707-829-0104 Opinions expressed reflect those of the author only.