Yet another async I/O issue: block devices
Martin.Wilck at fujitsu-siemens.com
Mon Nov 12 04:02:01 CST 2001
I just discovered yet another problem that arises for overlapped
I/O on normal disk files, more correctly, for any file on a block device.
Obviously IO requests on block devices on Linux are _always blocking_.
I wrote a very simple test program for reading from a floppy disk and
found exactly this behaviour, no matter if O_NONBLOCK was set or not.
"man 2 open" also says that O_NONBLOCK may or may not have any effect on
non-socket fd's and for block devices it clearly has none.
I don't know the reason for this, but it may have to do with Linux'
caching algorithms. This means that
- with ReadFile() etc. on regular files, the asynch code will never be
executed. Instead, the call will block when trying to read
immediately, and then return success.
- I am not 100% sure in what context the asynchronous handlers are
executed, but the read() write() calls there will be blocking as well.
I assume this is not what we want.
- I guess that for programs that "know" some IO is going to take a
lot of time (read()s on floppies, network file systems, ...) will
potentially be broken if they try to do overlapped IO and "do something
else" while the IO is executing. I do see the need, therefore, to
have an approach that mimics Windows' behaviour here.
- The only simple approach that I can see for making this happen is
creating a separate thread for reading/writing asynchronous IO.
The simplest approach would actually be to do a clone() for each async
request with CLONE_FILES | CLONE_VM | CLONE_PARENT.
I don't know how this would fit into Wine's general synchronization
approach - please give me hints.
- The separate thread itself would be very simple for files on block
devices, because it can simply execute the blocking read and finish when
the read finishes, leaving some status information somewhere.
- For other devices that _do_ support O_NONBLOCK, it may be cool to mimic
this simple behaviour by clone()ing too, dup() ing the fd, resetting
the O_NONBLOCK flag, and doing a blocking IO request just the same.
That means to basically leave it up to the kernel to handle
This would also mean that we wouldn't have to worry about differences
between files and sockets/pipes, because I'm 99% sure the kernel would
do it right.
I don't understand the concept of the wine service thread well enough yet
to judge if that could be used for doing what I just suggested. Perhaps
someone can help me out with that, I'll be studying the sources in the
PS. I guess another possible approach would be using raw I/O, but I am
very certain this is not what we want.
Martin Wilck Phone: +49 5251 8 15113
Fujitsu Siemens Computers Fax: +49 5251 8 20409
Heinz-Nixdorf-Ring 1 mailto:Martin.Wilck at Fujitsu-Siemens.com
D-33106 Paderborn http://www.fujitsu-siemens.com/primergy
More information about the wine-devel