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