Open oblique opened 4 years ago
This is also related to #594.
@oblique Have you solved this problem?
In general I was wrong about the File
being able to be used with mio, because regular files do not support asynchronous IO by the OS (unless if io-uring is used). So File::from_raw_fd
will be a wrong approach.
For the special files I now use async_io::Async<File>
from async-io crate. Just keep in mind this can not be used with regular files, otherwise executor may block.
The problem
I was working on a toy project and I couldn't get
/dev/ptmx
to work properly. To my surprise I found thatFile
is actually usingspawn_blocking
instead of mio or epoll. IMO this is costly, but I guess you balanced this cost with the cache buffer.Event if this implementation works well with simple files, it doesn't work at all with some special files because each special file has its own behavior.
Personally I worked only with two:
/dev/net/tun
read()
syscall always return one network packet, ifbuf
size if smaler than the packet data length, thenbuf
is filled with truncated data, the rest data are just lost.write()
syscall must write one complete network packet./dev/ptmx
read()
syscall reads thestdout
of the slave PTY, which means: no output for 5 minutes = blocks for 5 minutes.write()
syscall writes tostdin
of the slave PTY and must be immediate (i.e. not cached).In both cases cache can create misbehavior and in both cases
spawn_blocking
is very costly.Proposal
Under UNIX systems mio must be used. No cache buffering must be applied since it can create misbehavior. With this we have one more benefit,
File::from_raw_fd
can be used to as an equivalent of mio'sEventedFd
.If you really want cache then we can perform once the
fstat()
syscall on file descriptor and based onstat.st_rdev
we can choose the threaded/buffered implementation or the evented/unbuffered implementation.cc @yoshuawuyts @stjepang