When using the timer in the following code, either the "Error calling select"
error appears, otherwise new data is expected:
timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
if( select(s + 1, &readmask, NULL, NULL, &tv ) <= 0 )
{
perror("Error calling select");
return 0;
}
What can be done on the client without breaking the session in order to avoid this error when you re-access this code?
You should not be using <= 0
as the condition since 0
means timeout and < 0
means error.
Alternative:
if(int rv = select(s + 1, &readmask, NULL, NULL, &tv ); rv > 0) {
// success
} else if(rv == 0) {
// timeout
} else {
// error
}
What can be done on the client without breaking the session in order to avoid this error when you re-access this code?
If you get timeouts too quickly after you've changed the code to the above you should take a closer look at the timeout
parameter. You should reinitialize it before each call to select
:
"On Linux,
select()
modifiestimeout
to reflect the amount of time not slept; most other implementations do not do this. (POSIX.1
permits either behavior.) This causes problems both when Linux code which readstimeout
is ported to other operating systems, and when code is ported to Linux that reuses astruct timeval
for multipleselect()
s in a loop without reinitializing it. Consider timeout to be undefined afterselect()
returns."
...
"On Linux,
select()
also modifiestimeout
if the call is interrupted by a signal handler (i.e., theEINTR
error return). This is not permitted byPOSIX.1
."