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" ------------------------------------------------------------------ Joerg Kammererwrites: > 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...
As for the problems you're having with HTTP::Daemon... Have you considered posting this as a question on PerlMonks? If there's a better answer out there, surely the monks know it.
-sam
Re:Threads in 5.6 are bad, Win32 5.8 has ithreads
jjohn on 2002-11-20T14:44:45
Although AS Perl does have a kind of fork(), I understand that process creation is very slow on Win32. That Threading isn't really happening on 5.6.1 makes me feel less stupid for not getting it to work right.;-)