+
+ $noconns++;
+
+ dbg("Connection created ($noconns)") if isdbg('connll');
+ return bless $conn, $class;
+}
+
+sub set_error
+{
+ my $conn = shift;
+ my $callback = shift;
+ $conn->{eproc} = $callback;
+ set_event_handler($conn->{sock}, error => $callback) if exists $conn->{sock};
+}
+
+sub set_rproc
+{
+ my $conn = shift;
+ my $callback = shift;
+ $conn->{rproc} = $callback;
+}
+
+sub blocking
+{
+ return unless $blocking_supported;
+
+ # Make the handle stop blocking, the Windows way.
+ if ($blocking_supported) {
+ $_[0]->blocking($_[1]);
+ } else {
+ my $flags = fcntl ($_[0], F_GETFL, 0);
+ if ($_[1]) {
+ $flags &= ~O_NONBLOCK;
+ } else {
+ $flags |= O_NONBLOCK;
+ }
+ fcntl ($_[0], F_SETFL, $flags);
+ }
+}
+
+# save it
+sub conns
+{
+ my $pkg = shift;
+ my $call = shift;
+ my $ref;
+
+ if (ref $pkg) {
+ $call = $pkg->{call} unless $call;
+ return undef unless $call;
+ dbg("changing $pkg->{call} to $call") if isdbg('connll') && exists $pkg->{call} && $call ne $pkg->{call};
+ delete $conns{$pkg->{call}} if exists $pkg->{call} && exists $conns{$pkg->{call}} && $pkg->{call} ne $call;
+ $pkg->{call} = $call;
+ $ref = $conns{$call} = $pkg;
+ dbg("Connection $pkg->{cnum} $call stored") if isdbg('connll');
+ } 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;
+ foreach my $p (@pid) {
+ &{$p->{eproc}}($p, "$pid has gorn") if exists $p->{eproc};
+ $p->disconnect;
+ }
+}
+
+sub peerhost
+{
+ my $self = shift;
+ my $ip;
+ unless ($self->{peerhost}) {
+ $self->{peerhost} = $self->{sock}->peerhost;
+ }
+ return $self->{peerhost};
+}
+
+#-----------------------------------------------------------------
+# Send side routines
+sub connect {
+ my ($pkg, $to_host, $to_port, $rproc) = @_;
+
+ # Create a connection end-point object
+ my $conn = $pkg;
+ unless (ref $pkg) {
+ $conn = $pkg->new($rproc);
+ }
+ $conn->{peerhost} = $to_host;
+ $conn->{peerport} = $to_port;
+ $conn->{sort} = 'Outgoing';
+
+ # Create a new internet socket
+ my $sock = $io_socket->new();
+ return undef unless $sock;
+
+ my $proto = getprotobyname('tcp');
+ $sock->socket(AF_INET, SOCK_STREAM, $proto) or return undef;
+
+ blocking($sock, 0);
+ $conn->{blocking} = 0;
+
+ # does the host resolve?
+ my $ip = gethostbyname($to_host);
+ return undef unless $ip;
+
+ my $r = connect($sock, pack_sockaddr_in($to_port, $ip));
+ return undef unless $r || _err_will_block($!);
+
+ $conn->{sock} = $sock;
+ $conn->{peerhost} = $sock->peerhost; # for consistency
+
+ if ($conn->{rproc}) {
+ my $callback = sub {$conn->_rcv};
+ set_event_handler ($sock, read => $callback);