Reputation: 20688
I'm using select()
for non-blocking read()
from TCP socket. When select()
indicates there are data for reading I'm not sure if I still need to deal with EINTR
after read()
.
Upvotes: 2
Views: 477
Reputation: 19221
They way I understand the documentation (I didn't read through the kernel's code, so I may be wrong), the answer is: Yes.
If an interrupt occurs during the kernel's read
operation (when the kernel is copying data from the socket's buffer to the user's memory and updating the socket's state), the operation is canceled and the read
function will return -1
(with errno
set to EINTR
).
The fact that the socket is non-blocking only minimizes the "window" but it doesn't prevent this condition from taking place.
Also, even if this were not the case, I would recommend that you assume that EINTR
is possible. As long as the documentation doesn't state that an EINTR
error is invalid for non-blocking file descriptors, future updates to the kernel's implementation might invoke this error as they see fit.
Also, consider that even though the read
operation feels atomic to the application, the kernel is juggling a number of internal structures (the socket's read buffer alone has a number of elements that need to be updated after the memory was copied). For this reason, the internal structure has locking / synchronizing mechanisms. Even though the socket is non-blocking, there's still a window of time where the call could be interrupted.
Upvotes: 2
Reputation: 182761
Yes, absolutely. The select
function is a status reporting function that reports the status of something at some time in-between when you called select
and when you noticed its return value. It comes with absolutely no future guarantees whatsoever, period.
This is a very common misconception. But thinking that select
ensures a future operation will provide some particular result is as misguided as thinking that checking that there is free space on a disk means a future write won't fail. The implementation is permitted to fail a write with insufficient free space, in its judgement, even if you think there's enough free space. And the space can fill between finding the space and trying to use it.
The same is true with select
. There is no rule that the implementation must somehow remember that it gave you a hit on select
and have that affect the implementation of a subsequent read. People have made this assumption many times and gotten bitten by it horribly. Do not assume that just because you can't think of any way it can fail, that means it can't fail.
For example, no rule prohibits an implementation from doing the following:
select
returns ready to read. A read
issued at this instant would have returned the data.read
operation blocks since there is no data to read.If you think some standard prohibits it, please cite the standard. A read
after a select
hit can fail for any reason a read
before a select
hit could fail. The select
function never gives future guarantees.
Upvotes: 6