4 ms·
AFAIK, there's no reason why an OS can't make filesystem I/O non-blocking with the standard read/write/select (or poll or whatever) system calls. The only tric
by joosters 9y ago
AFAIK, there's no reason why an OS can't make filesystem I/O non-blocking with the standard read/write/select (or poll or whatever) system calls.
The only tricky part (API-side) is that write() is defined to confirm that some data got written, or not. If you let write() become non-blocking, and deferred the I/O, perhaps by returning immediately with EAGAIN or some such response, the write is is an unknown state to the rest of the application. What data can then be expected from other read() calls on that file from the same process? The old data? The new? A mix? You'd have to drop the POSIX consistency guarantee. For most programs, this is never likely to be an issue, as they don't tend to be re-reading bits of a file that they are also writing to, so it's a shame there's no option to let the write() be non-blocking if requested.
Issue 2 is failures: If the write, when it eventually happens, fails, you've got to have some way of passing that information back to the process. The solution for this seems easy enough; just let the FD become writeable again and the program will probably re-attempt the same write, at which time you can report the previous error.
Finally, making open() calls non-blocking would be the real API changer. If you defer all of the file opening work and give the application a file descriptor before doing any I/O, then you can hit all kinds of errors (permissions problems, file not found, and so on). How do you pass them back to the program? You can make any future read() or write() calls fail but these syscalls would now have to return error codes that they aren't specified as actually being able to return (read can't return things like EEXIST, EACCESS and so on). So the API is inadequate for these situations. You can see how they could be extended to cover these cases though.
- jzwinck 9y agoFile write could work the same as socket send. If the data cannot definitely be written now, write nothing and allow the application to try again, probably after waiting for readiness via poll or select.
- hoytech 9y agoSee gpderetta's comment elsewhere in this thread: the page-cache is different than socket mbufs in some pretty significant ways.