Messages in this thread | | | From | "Anthony Barbachan" <> | Subject | Re: User vs. Kernel (was: To be smug, or not to be smug, that isthe | Date | Sat, 23 Jan 1999 22:14:31 -0500 |
| |
>> This does not happen on Linux, at least not when using Libc 5, without >> undefining GNU or something like that. The GNU C library by default doesn't >> interrupt the read or write call when the process receives a signal. Its a >> nice feature, it allows me to leave out the error handling code that has to >> take care of this problem on SunOS and others by restarting the same system >> call; adjusted for any changes. > >Very nice, but sadly nonportable. Sounds like we need an all-Unix >conference to hash out an acceptable common solution, unless the majority >really, really loves writing #ifdef s. >
This is true, unless you compiled the GNU libc library on your favorite UNIX system. As most of the unix utilities packaged with commercial unixes basically suck (as compared to their GNU cousins) I already compile all the GNU utilities (anf compilers, etc) whenever possible on whatever system that I am working on; so compiling the GNU C library isn't much of a problem. Or you could just make a wrapper function "myread" that does the necesary error handling on the non-GNU-like systems. The real problem is that having system calls fail with an error that actually means, "call me again," is not intuitive and leads to having to added unnecesarily complicated code such as.
prereadlabel:
if((bytesread = read(...)) == -1) { if(errno == EINTR) goto prereadlabel;
// fatal read error handling code }
I dislike having to use a goto but its the cleanest method I've scene that takes care of this problem. The only other code that comes close to the above in cleaness, is actually more ambiguous; especially to the casual programmer or when quickly scanning code.
while((bytesread = read(...)) == -1) { if(errno != EINTR) { // fatal read error handling code // must end with either a break or a function return } }
Hopefully that all-unix (& unix-like) conference will decide to adopt the GNU way of doing things, at least in the area of system calls. Leave the more complicated code for the less common cases when the programmer actually wants his system call interrupted by a signal. Or better yet add a function that lets the programmer turn this behavior on and off per signal.
>VMS calls these ASTs, and every I/O function that could block accepts one. >This lets the application programmer definitively answer the question of >what to do with this I/O completion, instead of making the kernel guess. >It's a model I've come to appreciate, and if you'd rather be synchronous >you can call the blocking version (functionW() rather than function() ) >instead. But the price of this is that I/O had to be designed as >fundamentally asynchronous, and a synchronizing mechanism had to be >provided for the less-critical but more numerous cases where you want to >block. >
I'm not sure about having to design the system to be fundementally async in order to implement the above. It may be doable as it currently is by default with only the addition of a comparision that checks to see if the driver (or other kernel code) has been set to async mode by the process which has control over it and branching off of the default if it has been.
>But this would require revamping much of the fundamentals of the I/O code, >and the result would be so un-Unixy that I don't expect to see it in Linux >anytime soon. Possibly the time would be better spent building a whole
I agree with the above, although an alternative event based API could probably be made that coexists with the current systems calls. In this way Linux could have a new event based API for I/O and still remain backwardly compatable with UNIX in general.
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |