[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