SPUG: sockets, EWOULDBLOCK, classic textbook code
Fred Morris
m3047 at inwa.net
Sat Jul 12 14:38:20 PDT 2008
Here is some textbook code from the _Perl Cookbook_, 17.13, "Non-Forking
Servers":
if ($rv == length $outbuffer{$client} ||
$! == POSIX::EWOULDBLOCK) {
substr($outbuffer{$client}, 0, $rv) = '';
delete $outbuffer{$client} unless length $outbuffer{$client};
} else {
# Couldn't write all the data, and it wasn't because
# it would have blocked. Shutdown and move on.
delete $inbuffer{$client};
delete $outbuffer{$client};
delete $ready{$client};
$select->remove($client);
close($client);
next;
}
I ran into a situation where it seemed like processes which were writing (and
reading, but let's keep it simple) would die and packet traces confirmed no
FINs had been sent their way and there's no evidence that there has been any
sort of timeout or an excessive number of retries. So I started wondering
"hrmmm.. is EWOULDBLOCK not getting set? how can I test that?" and it dawned
on me that there was a simple change to the above which as far as I can
determine is non-harmful:
if ($rv > 0 ||
...
This didn't make the problem entirely go away entirely but it did reduce its
rate of occurrence. I put some additional error reporting code before the
close and that hasn't revealed some other informative message in $!. So, I
don't know what's going on, I just thought I'd toss it out in case it's
useful for anyone else or if anyone else has any insight.
This is Fedora on an Intel 64 bit processor (linux 2.6.23.17-88.fc7, gcc
4.1.2, posix threads, perl 5.8.8). The machine which the code was running on
has plenty of memory and disk and isn't particularly busy. It's talking to a
machine which is cranking through a lot of I/O and the network link is the
bottleneck.
--
Fred Morris
More information about the spug-list
mailing list