Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!usc!zaphod.mps.ohio-state.edu!think!masscomp!mouse!mitch From: mitch@mouse..westford.ccur.com (Mitchel Kuninsky) Newsgroups: comp.windows.x Subject: Re: Problem with Signals Message-ID: <23695@masscomp.ccur.com> Date: 5 Mar 90 23:19:56 GMT References: <9002281729.AA02895@wilkins.bcm.tmc.edu> <132399@sun.Eng.Sun.COM> Sender: news@masscomp.ccur.com Reply-To: mitch@westford.ccur.com (Mitchel Kuninsky) Organization: Concurrent Computer Corp. Westford MA. Lines: 67 argv wrote the following: >...long description of the problem with X and signals... > >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. > > >dan Are you suggesting that you do an XtAddWorkProc from the signal handler? You really can't even do that safely because the client code being interrupted by the signal might also be in the middle of a call to XtAddWorkProc and the workproc queue (or whatever database is used to keep track of them) might be in some inconsistent state. Just about the ONLY thing you can do safely from a signal handler is set a flag. One solution to this problem, as you mention in your message, is to set a flag and use a modified XtMainLoop that checks the flag upon return from XtNextEvent before calling XtDispatchEvent. I've implemented something like this and the one problem I have is that the arrival of the signal will not kick the client out of XtNextEvent so your signal handler will not get executed until some other event comes along. Usually, this is no problem, but, if the signal you're catching is SIGQUIT, there probably will not be any more events coming from the user. The real root of this problem, at least on Unix systems, is that the select in the Xlib tries to recover from being interrupted by a signal by checking errno for EINTR (which is the value returned when a system call is interrupted by a signal). If it finds EINTR, it just dives back into the select call. On the surface, it looks as though you could hack an Xlib to respond to signals by changing this behaviour so that XtNextEvent would return with a null event (or something) if it was interrupted and your special XtMainLoop could examine your signal flag. I envision a signal handler like: SignalHandler { sigFlag = TRUE; } and an XtMainLoop like: MyMainLoop() { XEvent event; for (;;) { XtNextEvent( &event ); if (event.type != NULL_EVENT) /* or something like this. */ XtDispatchEvent( &event ); if (sigFlag) { process signal. Inhibit signals. sigFlag = FALSE; Enable signals. } } }