From 9432e1bac162b909698fcb51e6435e1b1826f181 Mon Sep 17 00:00:00 2001 From: Matt Sergeant Date: Thu, 19 May 2005 15:39:53 +0000 Subject: [PATCH] Use SOMAXCONN which makes connections MUCH happier on high load servers git-svn-id: https://svn.perl.org/qpsmtpd/branches/high_perf@421 958fd67b-6ff1-0310-b445-bb7760255be9 --- qpsmtpd | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/qpsmtpd b/qpsmtpd index f69467d..f7076b5 100755 --- a/qpsmtpd +++ b/qpsmtpd @@ -27,7 +27,7 @@ $|++; # For debugging # $SIG{USR1} = sub { Carp::confess("USR1") }; -use Socket qw(IPPROTO_TCP SO_KEEPALIVE TCP_NODELAY SOL_SOCKET); +use Socket qw(SOMAXCONN IPPROTO_TCP SO_KEEPALIVE TCP_NODELAY SOL_SOCKET); $SIG{'PIPE'} = "IGNORE"; # handled manually @@ -207,7 +207,7 @@ sub run_as_server { Proto => IPPROTO_TCP, Blocking => 0, Reuse => 1, - Listen => 10 ) + Listen => SOMAXCONN ) or die "Error creating server $LOCALADDR:$PORT : $@\n"; IO::Handle::blocking($SERVER, 0); @@ -289,18 +289,8 @@ sub config_handler { return; } -# TODO: -# - Make number of accepts() we do dependant on whether MAXCONNIP is set - # Accept all new connections sub accept_handler { - my $max = $MAXCONNIP ? 100 : 1000; - for (1 .. $max) { - last if ! _accept_handler(); - } -} - -sub _accept_handler { my $running; if( $LineMode ) { $running = scalar keys %childstatus; @@ -309,12 +299,22 @@ sub _accept_handler { my $descriptors = Danga::Client->DescriptorMap; $running = scalar keys %$descriptors; } - if ($running >= $MAXCONN) { - ::log(LOGINFO,"Too many connections: $running >= $MAXCONN."); - return; + + my $max = $MAXCONNIP ? 100 : 1000; + + for (1 .. $max) { + if ($running >= $MAXCONN) { + ::log(LOGINFO,"Too many connections: $running >= $MAXCONN."); + return; + } + $running++; + last if ! _accept_handler($running); } - ++$running if $LineMode; # count self +} +sub _accept_handler { + my $running = shift; + my $csock = $SERVER->accept(); if (!$csock) { # warn("accept() failed: $!"); @@ -331,7 +331,6 @@ sub _accept_handler { if (!$LineMode) { # multiplex mode my $client = Qpsmtpd::PollServer->new($csock); - my $rem_ip = $client->peer_ip_string; if ($PAUSED) { $client->write("451 Sorry, this server is currently paused\r\n"); @@ -341,7 +340,8 @@ sub _accept_handler { if ($MAXCONNIP) { my $num_conn = 1; # seed with current value - + my $rem_ip = $client->peer_ip_string; + # If we for-loop directly over values %childstatus, a SIGCHLD # can call REAPER and slip $rip out from under us. Causes # "Use of freed value in iteration" under perl 5.8.4.