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

Reply via email to