[MPlayer-dev-eng] Re: kernel: to do_select(pipe) or not to do
Linus Torvalds
torvalds at osdl.org
Mon Nov 22 05:21:58 CET 2004
On Mon, 22 Nov 2004, Ivan Kalvachev wrote:
>
> You are very wrong at this point. A full write WILL block if it writes
> an PIPE_SIZE+1 bytes. And it have nothing to do with select()!
Don't bother arguing when you don't know what you're talking about.
As I already mentioned, "select()" usage ONLY MAKES SENSE FOR NONBLOCKING
FILE DESCRIPTORS.
Of _course_ a write() will block if the fd is blocking. But if you have a
nonblocking fd it will NOT block.
What "select()" returns is not whether something blocks or not. Never has
been. What the return value of select() means is whether you can do a
successful nonblocking write.
And yes, you _can_ do a successful nonblocking write of PIPE_BUF+1 bytes.
It won't do the _whole_ write (it will only do as much as it can), but the
point is, select _properly_ returned the fact that yes, you can write to
the fd.
> No need to send me samples, I have not send you the patch that I commit
> few weeks back, and it does indeed use O_NONBLOCK.
>
> But there is an fundamental problem with select() and pipes (not sure
> for other types). We don't know how big will be the write! So in case of
> 1 byte it does too paranoid and unnecessary blocking. In case of big
> write it will block.
No. If the pipe is set to nonblocking IT WILL NOT BLOCK. Not for a small
write, not for a big one. It will write "as much as it can", with the
added benefit that POSIX guarantees that small writes (as defined by
PIPE_BUF) are always atomic (ie they will be done fully or not done at
all, and a reader that has a sufficiently big buffer will see the whole
packet or none at all).
So there is no fundamental problem anywhere. Not for pipes, not for
sockets, not for anything. The only "fundamental" problem with select is
that
- it doesn't work for regular files (well, it "works" in the sense that
regular files are never considered to block at all)
- if you use select, you basically have to use O_NONBLOCK, or the
operation just doesn't make sense.
So I repeat, as I did in my example program: just do the damn write(), and
stop worrying about it. If you don't want to block, use O_NONBLOCK.
And never EVER try to use "select()" _before_ the write. You use select
after the write _fails_ with EAGAIN, not before. Select is not a "will
this write work", it's a "ok, the write didn't work, let's not try
immediately again, but instead wait until it might work".
I really thought my example program made that very clear.
Linus
More information about the MPlayer-dev-eng
mailing list