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?