dmh@goanna.oz (Darren Hosking) (09/20/89)
Due to the nature of System V signal handling it is possible for system calls within an X library (specifically Xlib) to be interrupted, ie the system call that was interrupted will return an error (-1) and errno will be set to EINTR. This is not a problem in _XRead(), which does a read() from the socket to the server, as the interrupted system call error is explicitly checked for and the XIOErrorFunction is NOT called if the read() was interrupted. However, in _XSend, which does a write() to the socket connected to the server, the interrupted system call error is not checked for and therefore the XIOErrorFunction will be called if the write() is interrupted. How can you use signal() and your own signal handlers without the client generating an error message and exiting (because of the interrupted syscall)? For example, if you want to run an infinite loop of X calls (drawing rectangles or whatever) which is stopped by a SIGALRM and a signal handler, how can you guarantee that system calls within Xlib (or other X libraries) will not be interrupted and abort? One solution is to ignore the given signal each time you want to call an Xlib function and then reinstate it after the call, but the system call overhead could be substantial. Any ideas or solutions? Thanks in advance, dmh Darren Hosking ACSnet: dmh@goanna.oz Department Of Computer Science ARPA: dmh%goanna.oz.au@uunet.uu.net RMIT CSNET: dmh%goanna.oz.au@australia GPO Box 2476V UUCP: ...!uunet!goanna.oz.au!dmh Melbourne Vic., Australia 3001
keith@EXPO.LCS.MIT.EDU (Keith Packard) (09/21/89)
> However, in _XSend, which does a write() to the socket connected to the > server, the interrupted system call error is not checked for and therefore > the XIOErrorFunction will be called if the write() is interrupted. > > How can you use signal() and your own signal handlers without the client > generating an error message and exiting (because of the interrupted syscall)? The problem with SysV is worse than you imagine. Write(2) blocks when the receiver buffer fills up. At this point, the signal may be processed, and the write(2) may return EINTR. But, the client has no way of discovering how many bytes were written to the socket *before* the write was blocked and then interrupted. If some data were sent to the server, the connection will become hopelessly out-of-sync. This is why the XIOErrorFunction is called when write(2) return EINTR; the client cannot continue using the current display connection. Read(2) doesn't have this trouble as it returns either whatever data is currently availible (without blocking) or waits for some data to arrive. When read(2) returns EINTR, no data could have been read yet. The only solution on native SysV is to use something other than signals. Keith Packard MIT X Consortium
davidp@labtam.oz (David Purdue) (09/21/89)
From article <2400@goanna.oz>, by dmh@goanna.oz (Darren Hosking): > Due to the nature of System V signal handling it is possible for system > calls within an X library (specifically Xlib) to be interrupted, ie the > system call that was interrupted will return an error (-1) and errno will > be set to EINTR. > > How can you use signal() and your own signal handlers without the client > generating an error message and exiting (because of the interrupted syscall)? > > For example, if you want to run an infinite loop of X calls (drawing > rectangles or whatever) which is stopped by a SIGALRM and a signal handler, > how can you guarantee that system calls within Xlib (or other X libraries) > will not be interrupted and abort? I just came across this problem while trying to do a benchmark with xbench. The situation is exactly as in the example above. What I do is this: I set up the signal handling routine using setsig(2), then around the call to Xlib in the relevant loop I put sighold(2) and sigrelse(2). Thus signal handling is turned off while X does its stuff. I have found that the system call overhead for doing this is not prohibitive, and it does not affect the xbench results because xbench always completes its operation before checking if the alarm went off anyway. DavidP ==== Mr. David Purdue Phone ISD: +61 3 587 1444 Fax: +61 3 580 5581 Labtam Information Telex: LABTAM AA33550 Systems Pty Ltd, 43 Malcolm Road, ACSnet/CSnet: davidp@labtam.oz BRAESIDE, ARPA: davidp%labtam.oz@uunet.uu.net VICTORIA, 3195. JANET: davidp@oz.labtam AUSTRALIA UUCP: ...!uunet!munnari!labtam.oz!davidp "Maybe I think too much." - Paul Simon
randy@erik.UUCP (Randy Brown) (09/21/89)
expo.lcs.mit.edu!keith (Keith Packard) writes: > The problem with SysV is worse than you imagine. Write(2) blocks when the > receiver buffer fills up. At this point, the signal may be processed, and the > write(2) may return EINTR. But, the client has no way of discovering how many > bytes were written to the socket *before* the write was blocked and then > interrupted. My copy of the draft for comment of FIPS151-1, changes to IEEE 1003.1 POSIX, says in part: In Section 6.4.2.2, the sentence "If a write() is interrupted by a signal after it successfully writes some data, either it shall return -1 with errno set to [EINTR] or it shall return the number of bytes written." shall be deleted and replaced with the sentence "If a write() is interrupted by a signal after it successfully writes some data, it shall return the number of bytes the system has written." So, as most major vendors like to sell to the feds, there's hope. Just start now making clear that you want the FIPS POSIX version and not the commercial POSIX version, which has a few more options to exercise that can introduce incompatibility. For example, FIPS POSIX must support job control (at the system call level), but IEEE POSIX has it optional. Of course, this doesn't necessarily solve this week's problems. ... rb