Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

should socket be set NON-BLOCKING before it is polled by select()?

I have the memory that when we want to use select() over a socket descriptor, this socket should be set NONBLOCKING in advance.

but today, I read a source file where there seems no lines which set socket to NON-BLOCKING Is my memory correct or not?

thanks!

like image 466
misteryes Avatar asked Sep 14 '25 04:09

misteryes


1 Answers

duskwuff has the right idea when he says

In general, you do not need to set a socket as non-blocking to use it in select().

This is true if your kernel is POSIX compliant with regard to select(). Unfortunately, some people use Linux, which is not, as the Linux select() man page says:

Under Linux, select() may report a socket file descriptor as "ready for reading", while nevertheless a subsequent read blocks. This could for example happen when data has arrived but upon examination has wrong checksum and is discarded. There may be other circumstances in which a file descriptor is spuriously reported as ready. Thus it may be safer to use O_NONBLOCK on sockets that should not block.

There was a discussion of this on lkml on or about Sat, 18 Jun 2011. One kernel hacker tried to justify the non POSIX compliance. They honor POSIX when it's convenient and desecrate it when it's not.

He argued "there may be two readers and the second will block." But such an application flaw is non sequiter. The kernel is not expected to prevent application flaws. The kernel has a clear duty: in all cases of the first read() after select(), the kernel must return at least 1 byte, EOF, or an error; but NEVER block. As for write(), you should always test whether the socket is reported writable by select(), before writing. This guarantees you can write at least one byte, or get an error; but NEVER block. Let select() help you, don't write blindly hoping you won't block. The Linux hacker's grumbling about corner cases, etc., are euphemisms for "we're too lazy to work on hard problems."

Suppose you read a serial port set for:

min N; with -icanon, set N characters minimum for a completed read

time N; with -icanon, set read timeout of N tenths of a second

min 250 time 1

Here you want blocks of 250 characters, or a one tenth second timeout. When I tried this on Linux in non blocking mode, the read returned for every single character, hammering the CPU. It was NECESSARY to leave it in blocking mode to get the documented behavior.

So there are good reasons to use blocking mode with select() and expect your kernel to be POSIX compliant.

But if you must use Linux, Jeremy's advice may help you cope with some of its kernel flaws.

like image 91
Trifle Menot Avatar answered Sep 15 '25 19:09

Trifle Menot