develooper Front page | perl.perl5.porters | Postings from October 2005

Multi-threaded IO::Socket

Thread Next
From:
Peter Millington
Date:
October 27, 2005 05:55
Subject:
Multi-threaded IO::Socket
Message ID:
000001c5da7c$eea4e130$0669a8c0@cs5c.co.uk
 
I have a fairly complex multi-threaded application, which uses IO::Socket
and Net::FTP from multiple threads, running on Windows XP SP2, ActiveState
Perl 5.8.6 build 811.
 
I found that Net::FTP (passive mode) would work in a standalone test
application but not when integrated into the multi-threaded environment.  Is
this object believed to be thread-safe?
 
The remote server saw the TCP port 21 connection handshake SYN-SYN-RST, i.e.
even initial three-way socket/connection open protocol was failing.
 
I believe that this was due to the IO::Socket::INET 'configure' routine not
correctly waiting for the socket to open, due to some unknown conflict with
multi-threading.  I have a modified version of this routine using sample
code acquired elsewhere, which uses a non-blocking tcp open and the
IO::Select can_write function with timeout.  I believe that this would not
work for all types of INET sockets, but works for the required TCP sockets
for Net::FTP. 
 
Is this approach appropriate?  Will a future release of this object be made
thread-safe?  Please can you reply directly, as I don't read the Perl mail
groups at the moment. Thanks.
 
I changed the 'configure' as follows:
 
----CUT
 return _error($sock, $EINVAL, "Bad hostname '",$arg->{PeerAddr},"'")
     unless defined $raddr;
 
#        my $timeout = ${*$sock}{'io_socket_timeout'};
#        my $before = time() if $timeout;
 
------ changes start here ---------
 
        # force nonblocking mode
        defined $sock->blocking(0)
             or return _error($sock, $!, "$!");

        undef $@;
        if ( ! ( $sock->connect(pack_sockaddr_in($rport, $raddr)) || $! ==
10035 || $! == 10036 ) ) {
            return _error($sock, $!, $^E )
        }
        if ( ! ( () =
IO::Select->new($sock)->can_write(${*$sock}{'io_socket_timeout'}) ) ) {
            return _error($sock, $!, $@ || "Timeout")
        }
 
        if (defined $arg->{Blocking}) {
           defined $sock->blocking($arg->{Blocking})
               or return _error($sock, $!, "$!");
        } else {
            $sock->blocking(1);
        }
        last;
 
---- changes end here ----
 
# if ($timeout) {
#     my $new_timeout = $timeout - (time() - $before);
#     return _error($sock,
#                         (exists(&Errno::ETIMEDOUT) ? Errno::ETIMEDOUT() :
$EINVAL),
#                         "Timeout") if $new_timeout <= 0;
#     ${*$sock}{'io_socket_timeout'} = $new_timeout;
#        }
 
    }

---CUT

____________________________________________________
CS5 Consultants Ltd
Registered in Scotland No. 263082

This e-mail message is confidential and for use by the addressee only. If
the message is received by anyone other than the addressee, please return
the message to the sender by replying to it and then delete the message from
your computer. Internet e-mails are not necessarily secure. CS5 Consultants
Ltd does not accept responsibility for changes made to this message after it
was sent.

Whilst all reasonable care has been taken to avoid the transmission of
viruses, spyware or other malware, it is the responsibility of the recipient
to ensure that the onward transmission, opening or use of this message and
any attachments will not adversely affect its systems or data. No
responsibility is accepted by CS5 Consultants in this regard and the
recipient should carry out such virus and other checks as it considers
appropriate.


 

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About