SocketFactory and Windows connections errors

[email protected] (Ciprian Hacman) Mon, 7 Feb 2011 11:04:58 +0200
Newsgroups perl.poe
Message-ID <[email protected]>
Hi everyone,

I am writing a cross platform script for testing some stuff, and I found an
issue with the Windows implementation for SocketFactory.
When connecting to a server that is not yet listening or cannot be reached,
the script just hangs. This happens with both ActiveState and Strawberry
perl.

Here is a test script that can reproduce this issue (there is no server
listening on port 1234):

use strict;
use warnings;

use POE;
use POE::Wheel::SocketFactory;

POE::Session->create(
    options => { trace => 1, debug => 1 },
    inline_states => {
        _start         => \&socket_init,
        sock_connected => \&socket_connected,
        sock_error     => \&socket_error,
    },
);

$poe_kernel->run();
exit 0;

sub socket_init {
    my $heap = $_[HEAP];
    $heap->{connect_wheel} = POE::Wheel::SocketFactory->new(
        RemoteAddress => 'localhost',
        RemotePort    => 1234,
        SuccessEvent  => 'sock_connected',
        FailureEvent  => 'sock_error',
    );
}

sub socket_connected {
    my $heap = $_[HEAP];
    delete $heap->{connect_wheel};
    print "Connected\n";
}

sub socket_error {
    my ( $heap, $syscall, $errno, $error ) = @_[ HEAP, ARG0 .. ARG2 ];
    $error = "Normal disconnection." unless $errno;
    warn "Client socket encountered $syscall error $errno: $error\n";
    delete $heap->{connect_wheel};
}


Running the script with "perl -d:Trace test_SF.pl" gives the folowing
output:

...
>> E:/Perl/site/lib/POE/Loop/Select.pm:157:   my $timeout =
$_next_event_time;
>> E:/Perl/site/lib/POE/Loop/Select.pm:159:   my $now = time();
>> E:/Perl/site/lib/POE/Loop/Select.pm:160:   if (defined $timeout) {
>> E:/Perl/site/lib/POE/Loop/Select.pm:161:     $timeout -= $now;
>> E:/Perl/site/lib/POE/Loop/Select.pm:162:     $timeout = 0 if $timeout <
0;
>> E:/Perl/site/lib/POE/Loop/Select.pm:171:   if (TRACE_EVENTS) {
>> E:/Perl/site/lib/POE/Loop/Select.pm:181:   if (TRACE_FILES) {
>> E:/Perl/site/lib/POE/Loop/Select.pm:195:   if (scalar keys %loop_filenos)
{
>> E:/Perl/site/lib/POE/Loop/Select.pm:199:     my $hits = CORE::select(


My workaround was to create the socket using the socket() function, but I
guess this is not the most elegant thing to do.

Is there another way to do this?