I have a C++ application that includes this function:
int
mySelect(const int fdMaxPlus1,
fd_set *readFDset,
fd_set *writeFDset,
struct timeval *timeout)
{
retry:
const int selectReturn
= ::select(fdMaxPlus1, readFDset, writeFDset, NULL, timeout);
if (selectReturn < 0 && EINTR == errno) {
// Interrupted system call, such as for profiling signal, try again.
goto retry;
}
return selectReturn;
}
Normally, this code work just fine, however, in one instance, I saw it get into an infinite loop where select()
keeps failing with the EINTR
errno
code. In this case, the caller had set the timeout to zero seconds and zero microseconds, meaning don't wait and return the select()
result immediately. I thought that EINTR
only occurs when a signal handler occurred, why would I keep getting a signal handler over and over again (for over 12 hours)? This is Centos 5. Once I put this into the debugger to see what was happening, the code returned without EINTR after a couple iterations. Note that the fd being checked is a socket.
I could add a retry limit to the above code, but I'd like to understand what is going on first.
On Linux, select(2) may modify the timeout argument (passed by address). So you should copy it after the call.
retry:
struct timeout timeoutcopy = timeout;
const int selectReturn
= ::select(fdMaxPlus1, readFDset, writeFDset, NULL, &timeoutcopy);
(in your code, your timeout
is probably zero or very small after a few or even the first iterations)
BTW, I suggest rather using poll(2) instead of select
(since poll
is is more C10K problem friendly)
BTW, EINTR
happens on any signal (see signal(7)), even without a registered signal handler.
You might use strace
to understand the overall behavior of your program.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With