+05Mar01=======================================================================
+1. do some major surgery on the connect logic to shorten the possibility of
+duplicate connects happening
04Mar01=======================================================================
1. allow fallback to english for help
03Mar01=======================================================================
}
$dxchan->disconnect;
push @out, $self->msg('disc2', $call);
- } elsif (my $out = grep {$_->{call} eq $call} @main::outstanding_connects) {
- unless ($^O =~ /^MS/i) {
- kill 'TERM', $out->{pid};
- }
- @main::outstanding_connects = grep {$_->{call} ne $call} @main::outstanding_connects;
- push @out, $self->msg('disc2', $call);
+ } elsif (my $conn = Msg->call($call)) {
+ $conn->disconnect;
} else {
push @out, $self->msg('e10', $call);
}
}
$dxchan->disconnect;
}
- my $out = grep {$_->{call} eq $call} @main::outstanding_connects;
- if ($out) {
- unless ($^O =~ /^MS/i) {
- kill 'TERM', $out->{pid};
- }
- @main::outstanding_connects = grep {$_->{call} ne $call} @main::outstanding_connects;
- }
}
# start a connect process off
my $call = uc shift;
my $lccall = lc $call;
- if (grep {$_->{call} eq $call} @main::outstanding_connects) {
+ if (Msg->conns($call)) {
dbg('cron', "Connect not started, outstanding connect to $call");
return;
}
# send initialisation string
unless ($self->{outbound}) {
-# $self->send(pc38()) if DXNode->get_all();
$self->send(pc18());
$self->{lastping} = $main::systime;
} else {
- # remove from outstanding connects queue
- @main::outstanding_connects = grep {$_->{call} ne $call} @main::outstanding_connects;
- $self->{lastping} = $main::systime + $self->pingint / 2;
+ $self->{lastping} = $main::systime + ($self->pingint / 2);
}
$self->state('init');
$self->pc50_t(time);
} elsif ($conn->{state} eq 'WL' ) {
$msg = uc $msg;
if (is_callsign($msg)) {
+ &{$conn->{rproc}}($conn, "A$msg|telnet");
_send_file($conn, "$main::data/connected");
- $conn->{call} = $msg;
- &{$conn->{rproc}}($conn, "A$conn->{call}|telnet");
$conn->{state} = 'C';
} else {
$conn->send_now("Sorry $msg is an invalid callsign");
my $call = shift;
my $fn = shift;
my $conn = ExtMsg->new(\&main::rec);
- $conn->{call} = $call;
+ $conn->conns($call);
my $f = new IO::File $fn;
push @{$conn->{cmd}}, <$f>;
$f->close;
- push @main::outstanding_connects, {call => $call, conn => $conn};
$conn->_dotimeout($deftimeout);
$conn->_docmd;
}
}
last if $conn->{state} eq 'E';
}
- unless (exists $conn->{cmd} && @{$conn->{cmd}}) {
- @main::outstanding_connects = grep {$_->{call} ne $conn->{call}} @main::outstanding_connects;
- }
}
sub _doconnect
my $conn = shift;
dbg('connect', "timed out after $conn->{timeval} seconds");
$conn->disconnect;
- @main::outstanding_connects = grep {$_->{call} ne $conn->{call}} @main::outstanding_connects;
}
# handle callsign and connection type firtling
use strict;
use IO::Select;
use IO::Socket;
-#use DXDebug;
+use Carp;
-use vars qw(%rd_callbacks %wt_callbacks $rd_handles $wt_handles $now @timerchain);
+use vars qw(%rd_callbacks %wt_callbacks $rd_handles $wt_handles $now @timerchain %conns);
%rd_callbacks = ();
%wt_callbacks = ();
return bless $conn, $class;
}
+# save it
+sub conns
+{
+ my $pkg = shift;
+ my $call = shift;
+ my $ref;
+
+ if (ref $pkg) {
+ $call = $pkg->{call} unless $call;
+ return undef unless $call;
+ confess "changing $pkg->{call} to $call" if exists $pkg->{call} && $call ne $pkg->{call};
+ $pkg->{call} = $call;
+ $ref = $conns{$call} = $pkg;
+ } else {
+ $ref = $conns{$call};
+ }
+ return $ref;
+}
+
+# this is only called by any dependent processes going away unexpectedly
+sub pid_gone
+{
+ my ($pkg, $pid) = @_;
+
+ my @pid = grep {$_->{pid} == $pid} values %conns;
+ for (@pid) {
+ if ($_->{rproc}) {
+ &{$_->{rproc}}($_, undef, "$pid has gorn");
+ } else {
+ $_->disconnect;
+ }
+ }
+}
+
#-----------------------------------------------------------------
# Send side routines
sub connect {
$conn->{state} = 'E';
delete $conn->{cmd};
$conn->{timeout}->del_timer if $conn->{timeout};
- return unless defined($sock);
+
+ # be careful to delete the correct one
+ if (my $call = $conn->{call}) {
+ my $ref = $conns{$call};
+ delete $conns{$call} if $ref && $ref == $conn;
+ }
+
set_event_handler ($sock, "read" => undef, "write" => undef);
+ unless ($^O =~ /^MS/i) {
+ kill 'TERM', $conn->{pid} if exists $conn->{pid};
+ }
+ return unless defined($sock);
shutdown($sock, 3);
close($sock);
}
$version = "1.47"; # the version no of the software
$starttime = 0; # the starting time of the cluster
$lockfn = "cluster.lock"; # lock file name
-@outstanding_connects = (); # list of outstanding connects
+#@outstanding_connects = (); # list of outstanding connects
@listeners = (); # list of listeners
# is there one already connected to me - locally?
my $user = DXUser->get($call);
- if (DXChannel->get($call)) {
+ if ($sort ne 'O' && Msg->conns($call)) {
my $mess = DXM::msg($lang, ($user && $user->is_node) ? 'concluster' : 'conother', $call, $main::mycall);
already_conn($conn, $call, $mess);
return;
return;
}
+ # mark him up
+ $conn->conns($call) unless $sort eq 'O';
+
# create the channel
$dxchan = DXCommandmode->new($call, $conn, $user) if $user->is_user;
$dxchan = DXProt->new($call, $conn, $user) if $user->is_node;
my $cpid;
while (($cpid = waitpid(-1, WNOHANG)) > 0) {
dbg('reap', "cpid: $cpid");
- @outstanding_connects = grep {$_->{pid} != $cpid} @outstanding_connects;
+# Msg->pid_gone($cpid);
$zombies-- if $zombies > 0;
}
dbg('reap', "cpid: $cpid");