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