Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

jjohn (22)

jjohn
  (email not shown publicly)
http://taskboy.com/
AOL IM: taskboy3000 (Add Buddy, Send Message)

Perl hack/Linux buff/OSS junkie.

Journal of jjohn (22)

Tuesday November 19, 2002
10:47 PM

HTTP::Daemon and 'broken pipe' errors

[ #9030 ]

I'm working on a game similar to Funeral Quest (an upgrade to which is due soon). It's a turned-based web game based on UFOlogy (go with what you know, I say). I'll have details on the game some. Naturally, the game is written in Perl.

The game includes a single-threaded web server implemented with Gisle Aas' HTTP::Daemon Class. It's single-threaded because I want to allow users to run the server on Winders, should they choose to and I couldn't figure out how to use threads or ithreads (am I supposed to have access to ithreads?) on win32.

For simple tests, getting a file or a small web page, HTTP::Daemon works fine. The problem started when it attempted to serve a web page with 15 images on it. When the server tried to server the third file (an image), I'd get a 'broken pipe' error my server would halt. As I worked to isolate the problem, I found that the error was coming from this simple loop in HTTP::Daemon::ClientConn::send_file:

    while ($n = sysread($file, $buf, 8*1024)) {
        last if !$n;
        $cnt += $n;
    print $self $buf;
    }

As I step through this code in the debugger, I found that after the second iteration $self (a kind of IO::Socket::INET object) would choke. Bummer. I tried changing from print to syswrite, but that didn't change the behavoir at all.

I turned to Google.

Digging around, I found this post from 1997:

Gisle Aas (gisle@aas.no)
26 Nov 1997 11:39:19 +0100

Previous message: Gisle Aas: "Re: libwww-per-5.16"
In reply to: Joerg Kammerer: "Broken Pipe"

------------------------------------------------------------------

J oerg Kammerer <jk@schlund.de> writes:

> Hope for a Tip...

Add:

   $SIG{'PIPE'} = 'IGNORE';

to your script.

Sure enough, that seems to do the trick. An early hack I thought of that sort of worked was:

$SIG{WARN} = sub { exec "/usr/bin/perl $0" };

This restarts the server on a broken PIPE error. Unfortunately, the file that choke the server wouldn't get sent.

It would be super if Gisle added this little gotcha to his HTTP::Daemon man page. If not, I'm sure others will find this journal page when they Google for a solution, as I did.

Guru advice is welcomed. Any thoughts on why the server connection chokes? It looks like some kind of I/O buffer is getting full. Because I can safely ignore the signal, I'm guessing that the I/O that trigger the signal gets cleared and more traffic is accepted on that socket. Is this some kind of race condition?

Also, should I abandon the fantasy of expecting perl 5.6.1 threading to work reliably on both Linux and Windows?

You guys are the best...

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • Yes. Immediately abandon the fantasy of getting 5.6.1 threads stable anywhere. Perl's threading support isn't even close to stable until 5.8.0, and even then there are a few problems left to deal with. I wrote an article about threading in Perl [perl.com] that you might find useful.

    As for the problems you're having with HTTP::Daemon... Have you considered posting this as a question on PerlMonks [perlmonks.org]? If there's a better answer out there, surely the monks know it.

    -sam

  • 5005 threads and ithreads in 5.6 are just broken, to get atleast working threads you need 5.8 with ithreads. I would bet that most win32 6.8 users have ithread enable, the default makefile enables them, and so does ActiveState to allow for psuedo-fork to work.
    --
    sky