Hi, I have just come up with another approach that completely removes the alarm() calls and just uses select().
Could you try this. Mark commit 5154023053d20e610879cd0a1ee22a8916cd9747 Author: Mark Hindley <m...@hindley.org.uk> Date: Wed Nov 25 15:00:40 2009 +0000 Another approach: Don't use alarm() at all, but use IO::Select->can_read timeouts in a while loop diff --git a/apt-cacher b/apt-cacher index 9db5fa0..f2c9289 100755 --- a/apt-cacher +++ b/apt-cacher @@ -1153,89 +1153,73 @@ sub connect_curlm { my $active_handles = 0; my $idcounter=1; - eval { - local $SIG{__DIE__} = 'IGNORE'; # Prevent log verbosity - local $SIG{ALRM} = sub { - unless ($active_handles || $select->can_read(0)) { - $select->remove($server); - $server->close; - die "libcurl inactive\n"; + while ($select->can_read($cfg->{curl_idle_timeout})) { + LIBCURL_REQUEST: + my $client = $server->accept(); + debug_message("libcurl: connection from $client"); + # deal with connection here + while (<$client>) { + chomp; + my ($curl_req,$headonly,@cache_control) = thaw($_); # Decode request + debug_message("Libcurl: thawed request $curl_req, $headonly, @cache_control"); + # Verify input + unless ($curl_req =~ m!^http://[-~\w+\.]+!i) { + info_message("Error: [libcurl] Bad request received $_"); + $client->close; + next LIBCURL_REQUEST; + } + $client->shutdown(0); # Finished reading + + my $curl = ${&init_curl}; + $easy{$idcounter}=[$client,$curl]; + debug_message("Add curl handle #$idcounter: for $curl_req"); + $curl->setopt(CURLOPT_PRIVATE,$idcounter++); # Assign Multi ID + # attach to WWW::Curl::Multi + $curlm->add_handle($curl); + + if($headonly) { + debug_message ('libcurl: setting up for HEAD request'); + $curl->setopt(CURLOPT_NOBODY,1); } else { - alarm $cfg->{curl_idle_timeout} + debug_message ('libcurl: setting up for GET request'); + $curl->setopt(CURLOPT_HTTPGET,1); + $curl->setopt(CURLOPT_FILE, $client); } - }; - alarm $cfg->{curl_idle_timeout}; # Set initial timeout - - LIBCURL_REQUEST: - while (my $client = $server->accept()) { - debug_message("libcurl: connection from $client"); - # deal with connection here - while (<$client>) { - chomp; - my ($curl_req,$headonly,@cache_control) = thaw($_); # Decode request - debug_message("Libcurl: thawed request $curl_req, $headonly, @cache_control"); - # Verify input - unless ($curl_req =~ m!^http://[-~\w+\.]+!i) { - info_message("Error: [libcurl] Bad request received $_"); - $client->close; - next LIBCURL_REQUEST; - } - $client->shutdown(0); # Finished reading - - my $curl = ${&init_curl}; - $easy{$idcounter}=[$client,$curl]; - debug_message("Add curl handle #$idcounter: for $curl_req"); - $curl->setopt(CURLOPT_PRIVATE,$idcounter++); # Assign Multi ID - # attach to WWW::Curl::Multi - $curlm->add_handle($curl); - if($headonly) { - debug_message ('libcurl: setting up for HEAD request'); - $curl->setopt(CURLOPT_NOBODY,1); - } - else { - debug_message ('libcurl: setting up for GET request'); - $curl->setopt(CURLOPT_HTTPGET,1); - $curl->setopt(CURLOPT_FILE, $client); - } - - push @cache_control, 'Pragma:' if ! grep /^Pragma:/, @cache_control; # Override libcurl default. - $curl->setopt(CURLOPT_HTTPHEADER, \...@cache_control); - $curl->setopt(CURLOPT_URL, $curl_req); - $curl->setopt(CURLOPT_WRITEHEADER, $client); - - $active_handles++; + push @cache_control, 'Pragma:' if ! grep /^Pragma:/, @cache_control; # Override libcurl default. + $curl->setopt(CURLOPT_HTTPHEADER, \...@cache_control); + $curl->setopt(CURLOPT_URL, $curl_req); + $curl->setopt(CURLOPT_WRITEHEADER, $client); + + $active_handles++; - while ($active_handles) { - my $active_transfers = $curlm->perform; - if ($active_transfers != $active_handles) { - if (my ($id,$return_value) = $curlm->info_read) { - debug_message("curl handle #$id completed, status: $return_value"); - if ($id) { - $active_handles--; - my($client_socket,$client_curl)=...@{$easy{$id}}; - print $client_socket "__APT-CACHER_LIBCURL_EOF__\n"; - print $client_socket freeze ($return_value, $client_curl->errbuf)."\n"; - $client_socket->shutdown(2); # Done - delete $easy{$id}; - debug_message("libcurl active transfers: $active_transfers"); - } + while ($active_handles) { + my $active_transfers = $curlm->perform; + if ($active_transfers != $active_handles) { + if (my ($id,$return_value) = $curlm->info_read) { + debug_message("curl handle #$id completed, status: $return_value"); + if ($id) { + $active_handles--; + my($client_socket,$client_curl)=...@{$easy{$id}}; + print $client_socket "__APT-CACHER_LIBCURL_EOF__\n"; + print $client_socket freeze ($return_value, $client_curl->errbuf)."\n"; + $client_socket->shutdown(2); # Done + delete $easy{$id}; + debug_message("libcurl active transfers: $active_transfers"); } } - # Check for pending new request - if ($active_handles && $select->can_read(0)) { - debug_message('Pending connection'); - next LIBCURL_REQUEST; - } + } + # Check for pending new request + if ($active_handles && $select->can_read(0)) { + debug_message('Pending connection'); + next LIBCURL_REQUEST; } } } - }; - unlink ($cfg->{libcurl_socket}); - if ($@ and $@ !~ /libcurl inactive\n/) { - die "Libcurl alarm error: $@" } + + unlink ($cfg->{libcurl_socket}); debug_message("Libcurl thread inactive. Exiting"); exit(0); } -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org