I am trying to make a HTTP::Daemon test server that can service 2 clients simultaneously on Windows. Ithreads fork is the easiest thing to use I suppose for a test server. I am using "v5.10.1 built for MSWin32-x86-multi-thread" ActivePerl build 1007. If I comment out the fork and uncomment " #$pid = 0;" (remember the "exit(0);" too) the script works fine, but can service only 1 client at a time. I also tried the forking version of this script on Linux with perl 5.8.8, it worked perfectly.
According to Visual Studio debugger, it tells me perl is deadlocked when I break it.
The callstack on the child thread is
ntdll.dll!_KiFastSystemCallRet@0()
ntdll.dll!_ZwWaitForSingleObject@12() + 0xc
ntdll.dll!_RtlpWaitForCriticalSection@4() + 0x8c
ntdll.dll!_RtlEnterCriticalSection@4() + 0x46
mswsock.dll!_WSPGetSockName@16() + 0x8e
ws2_32.dll!_getsockname@12() + 0x4d
> perl510.dll!win32_getsockname(unsigned int s=, sockaddr * addr=,
+int * addrlen=) Line 197 + 0x29 C
The callstack on the main perl thread is
ntdll.dll!_KiFastSystemCallRet@0()
ntdll.dll!_ZwDeviceIoControlFile@40() + 0xc
mswsock.dll!_WSPAccept@24() + 0x1f5
ws2_32.dll!_WSAAccept@20() + 0x85
ws2_32.dll!_accept@12() + 0x17
> perl510.dll!win32_accept(unsigned int s=2382008, sockaddr * addr=
+0x00000003, int * addrlen=0x0140f6e4) Line 160 + 0x29 C
perl510.dll!Perl_pp_accept(interpreter * my_perl=0x01c75b3c) Lin
+e 2588 C
perl510.dll!Perl_runops_standard(interpreter * my_perl=0x00243fbc
+) Line 38 + 0xc C
perl510.dll!S_run_body(interpreter * my_perl=0x00243fbc, long old
+scope=1) Line 2432 + 0x7 C
perl510.dll!perl_run(interpreter * my_perl=0x00243fbc) Line 2350
+ + 0xa C
perl510.dll!RunPerl(int argc=2, char * * argv=0x00243f08, char *
+* env=0x01242c10) Line 270 + 0x6 C++
perl.exe!main(int argc=2, char * * argv=0x00243f08, char * * env=
+0x00242c10) Line 22 + 0x12 C
perl.exe!_mainCRTStartup() + 0xe3
kernel32.dll!_BaseProcessStart@4() + 0x23
Callstack in Perl before the freeze is
Socket.pm, line 246, in IO::Socket::sockname
INET.pm, line 270, in IO::Socket::sockaddr
Daemon.pm, line 42, in HTTP::Daemon::url
Daemon.pm, line 147, in HTTP::Daemon::ClientConn::get_request
httpserverfork.pl, line 24, in main
The script is
#!/usr/bin/perl -w
use HTTP::Daemon;
use warnings;
use strict;
$HTTP::Daemon::DEBUG =1;
my $page = "Hello World!";
my $httpresponsestr = "HTTP/1.1 200 OK\nConnection: close\nDate: Sat,
+16 Oct 2010 04:41:51 GMT\nCache-Control: no-store, no-cache, must-rev
+alidate\nContent-Length: ".length($page)."\n\n".$page;
$| = 1;
my $d = HTTP::Daemon->new (LocalPort => 80) || die "server died";
print "Please contact me at: <URL:", $d->url, ">\n";
while (my $c = $d->accept) {
my $pid = fork();
#my $pid = 0;
if(!defined($pid))
{die "Fork failed."}
elsif ($pid == 0)
{
my $sn;
$sn = $c->sockaddr;
$sn = $c->sockname;
my $r = $c->get_request;
print "after get_request r\n";
if ($r->method eq 'GET') {
print "is a get\n";
$c->print($httpresponsestr);
}
else {
print "forbidden";
$c->send_error(RC_FORBIDDEN());
}
$c->close;
print "closed\n";
#comment this out when fork disabled
exit(0);
}
print "fork parent out\n";
}
Whats wrong with my code? Does perl's fork not support sockets?