[EMAIL PROTECTED] wrote on Mon, 10 Dec 2007 21:19 -0600:
> while a loop will fix it, it would be really nice to understand how we get
> EAGAIN when we think that there are bytes there...
[..]
> On Dec 7, 2007, at 4:55 PM, Sam Lang wrote:
>> I'm seeing recv on a socket in non-blocking mode returning EAGAIN
>> occasionally, even though epoll has just told us there's bytes waiting. I
>> guess that's why the call was initially a blocking recv. I can add a loop
>> around the non-blocking recv while it returns EAGAIN, unless someone can
>> think of a better work around.
The function is getting a bit messy. I'm all for looping on E* and
thought Sam's original mail made sense. But on second glance:
int BMI_sockio_nbrecv(int s,
void *buf,
int len)
{
int ret, comp = len;
assert(fcntl(s, F_GETFL, 0) & O_NONBLOCK);
while (comp)
{
nbrecv_restart:
ret = recv(s, buf, comp, DEFAULT_MSG_FLAGS);
if (!ret) /* socket closed */
{
errno = EPIPE;
return (-1);
}
if (ret == -1 && errno == EWOULDBLOCK)
{
return (len - comp); /* return amount completed */
}
if (ret == -1 && (errno == EINTR || errno == EAGAIN))
{
goto nbrecv_restart;
}
else if (ret == -1)
{
return (-1);
}
comp -= ret;
buf = (char *)buf + ret;
}
return (len - comp);
}
Note that we get from standard headers:
/usr/include/asm-generic/errno.h:#define EWOULDBLOCK EAGAIN /*
Operation would block */
But maybe there are some systems where this is not true? Not ones
that use glibc, apparently.
Anyway, the first use of EWOULDBLOCK runs us back to the poll
loop, which is the right thing to do. The second use of EAGAIN
would lead to a busy loop on recv()->EAGAIN that isn't quite so
nice. But that code never gets hit.
I'm not sure that a poll readable result necessarily means we'll get
any bytes on the socket. There are numerous ways in which things
can get messy.
-- Pete
_______________________________________________
Pvfs2-developers mailing list
[email protected]
http://www.beowulf-underground.org/mailman/listinfo/pvfs2-developers