Sie schrieben: Hi i found how to solve that problem. The solution is non blocking sockets.
However, thank you anyways. I would appreciate if someone has a better solution. But I guess there isn't one, since it seems impossible to implement a alarm signal inti threads, and nor cancle a detached thread.
Hi, i wrote a prethreading server deamon that also reuse finished threads. However I have a problem with possibel DOS attacks. $fh is the my $STATUS = ''; my %STATUSTIME = 0; my $ACCEPT_LOCK = ''; my %STATUS = (); my $DONE = 0; share(%STATUS); share(%STATUSTIME); share($ACCEPT_LOCK); $SIG{INT} = $SIG{TERM} = sub { $DONE++ }; $SIG{ALRM} = sub {}; #MAIN Webserver with Multithreading print "Binding socket on $ip_listen Port $port_listen\n"; #Bind Socket my $socket = IO::Socket::INET->new( LocalPort => $port_listen, LocalAddr => $ip_listen, Listen => 100,Reuse => 1 ) or die "Can't create listen socket: $!";my $SOCKIN = IO::Select->new($socket); launch_thread($socket) for (1..$PRETHREAD); # launch threads while (!$DONE) { lock %STATUS; cond_wait %STATUS; warn join(' ', map {"$_=>$STATUS{$_}"} keys %STATUS),"\n" if DEBUG; my @idle = sort {$a <=> $b} grep {$STATUS{$_} eq 'idle'} keys %STATUS; my @busy = sort {$a <=> $b} grep {$STATUS{$_} eq 'busy'} keys %STATUS; if (@idle < $LO_WATER_MARK) {launch_thread($socket) for ([EMAIL PROTECTED]); # bring the number up} elsif (@idle > $HI_WATER_MARK) {my @goners = @[EMAIL PROTECTED] - $HI_WATER_MARK - 1]; # kill the oldest onesstatus($_ => 'goner') foreach @goners; warn "decomissioning @goners\n" if DEBUG; } if (scalar(@busy) > $threadsmaxbusy) { $threadsmaxbusy=scalar(@busy); } } warn "Server will terminate when last thread has finished...\n" if DEBUG; status($_ => 'goner') foreach keys %STATUS; exit 0; sub do_thread { my $socket = shift; my $cycles = $MAX_REQUEST; my $tid = threads->self->tid; my $c; warn "Thread $tid: starting\n" if DEBUG; threads->self->detach; # don't save thread status info $SIG{__DIE__} = sub {&status($tid=>undef);close $c;}; status($tid => 'idle'); while (status($tid) ne 'goner' && $cycles > 0) { next unless $SOCKIN->can_read(1); { lock $ACCEPT_LOCK; next unless $c = $socket->accept(); } $cycles--; status($tid => 'busy'); $STATUSTIME{$tid}=time; warn "Thread $tid: handling connection\n" if DEBUG; new_connection($c); close $c; status($tid => 'idle'); } warn "Thread $tid done\n" if DEBUG; status($tid=>undef); exit 1; } sub status { my $tid = shift; lock %STATUS; return $STATUS{$tid} unless @_; my $status = shift; if ($status) { $STATUS{$tid} = $status unless defined $STATUS{$tid} and $STATUS{$tid} eq 'goner'; } else { delete $STATUS{$tid}; delete $STATUSTIME{$tid}; } cond_broadcast %STATUS; } sub new_connection { my $fh = shift; my $ip = ""; my $port = ""; my $iaddr = ""; my $return = eval(($port, $iaddr) = sockaddr_in(getpeername($fh))); if ($return) { $ip=inet_ntoa($iaddr); binmode $fh; my $doexit = 0; my %req; $req{HEADER}={}; my $request_line = <$fh>; <== Here is the problem .... if i write a simple cgi-script use IO::Socket;my $socket = new IO::Socket::INET( PeerAddr => $deamonserver, PeerPort => 80, Proto => 'tcp', );if ($socket) { my $counter=0; while (1) { sleep 1; $counter++; print "$counter\n"; } close($socket); } The server will never break out the thread With forking servers I used to do it with ALRM signal, but this doesn't work with threads. Any solution? I am searching arround the net now for more than one week, and didn't didn't find any solution. Neither socket timeout works nor any signal handler modul I tired. Thank you for helping
