When using PoCo::Client::Ping I would get both the ping response
event 'pong' and a timeout for the same 'ping' request. It seems
to me that the correct behavior is to get a 'pong' XOR a timeout.

However, the timeout is where the cleanup occurs for the
PoCo::Client::Ping internal data structures. So I copied & tweaked
the cleanup cleanup code to the end of the poco_ping_pong() event
handler.

Also there looked like a typo (spurious comma) where setting the delay.

Here is the patch.


-Leo.

--- Ping.pm-orig        Sun Feb 17 15:33:38 2002
+++ Ping.pm     Sun Feb 17 15:53:07 2002
@@ -170,7 +170,7 @@
   send($heap->{socket_handle}, $msg, ICMP_FLAGS, $socket_address) or die $!;
 
   # Set a timeout based on the sequence number.
-  $kernel->delay( $seq, => $timeout );
+  $kernel->delay( $seq => $timeout );
 
   # Record information about the ping request.
   $heap->{ping_by_seq}->{$seq} =
@@ -288,6 +288,27 @@
   $heap->{ping_by_seq}->{$from_seq}->[PBS_POSTBACK]->
     ( inet_ntoa($from_ip), $trip_time, $now
     );
+
+  # Disable timer
+  $kernel->delay($seq);
+
+  # Delete the ping information, but cache a copy for other work.
+  my $ping_info = delete $heap->{ping_by_seq}->{$seq};
+
+  # Stop mapping the session+address to this sequence number.
+  delete( $heap->{addr_to_seq}->
+         {$ping_info->[PBS_SESSION]}->{$ping_info->[PBS_ADDRESS]}
+       );
+
+  # Stop tracking the session if that was the last address.
+  delete $heap->{addr_to_seq}->{$ping_info->[PBS_SESSION]}
+    unless scalar(keys %{$heap->{addr_to_seq}->{$ping_info->[PBS_SESSION]}});
+
+  # Close the socket if there are no sessions waiting for responses.
+  unless (scalar keys %{$heap->{ping_by_seq}}) {
+    DEBUG_SOCKET and warn "closing the raw icmp socket";
+    $kernel->select_read( delete $heap->{socket_handle} );
+  }
 }
 
 # Default's used to catch ping timeouts, which are named after the
--- Ping.pm-orig        Sun Feb 17 15:33:38 2002
+++ Ping.pm     Sun Feb 17 15:53:07 2002
@@ -170,7 +170,7 @@
   send($heap->{socket_handle}, $msg, ICMP_FLAGS, $socket_address) or die $!;
 
   # Set a timeout based on the sequence number.
-  $kernel->delay( $seq, => $timeout );
+  $kernel->delay( $seq => $timeout );
 
   # Record information about the ping request.
   $heap->{ping_by_seq}->{$seq} =
@@ -288,6 +288,27 @@
   $heap->{ping_by_seq}->{$from_seq}->[PBS_POSTBACK]->
     ( inet_ntoa($from_ip), $trip_time, $now
     );
+
+  # Disable timer
+  $kernel->delay($seq);
+
+  # Delete the ping information, but cache a copy for other work.
+  my $ping_info = delete $heap->{ping_by_seq}->{$seq};
+
+  # Stop mapping the session+address to this sequence number.
+  delete( $heap->{addr_to_seq}->
+         {$ping_info->[PBS_SESSION]}->{$ping_info->[PBS_ADDRESS]}
+       );
+
+  # Stop tracking the session if that was the last address.
+  delete $heap->{addr_to_seq}->{$ping_info->[PBS_SESSION]}
+    unless scalar(keys %{$heap->{addr_to_seq}->{$ping_info->[PBS_SESSION]}});
+
+  # Close the socket if there are no sessions waiting for responses.
+  unless (scalar keys %{$heap->{ping_by_seq}}) {
+    DEBUG_SOCKET and warn "closing the raw icmp socket";
+    $kernel->select_read( delete $heap->{socket_handle} );
+  }
 }
 
 # Default's used to catch ping timeouts, which are named after the

Reply via email to