summaryrefslogtreecommitdiff
path: root/dist/IO
diff options
context:
space:
mode:
authorKarthik Rajagopalan <rajagopa@pauline.schrodinger.com>2011-07-14 13:36:41 -0400
committerSteve Hay <steve.m.hay@googlemail.com>2011-08-15 21:17:20 +0100
commitf1d35e3443aa8451bf47be80983076fe28626113 (patch)
treed12198868746fab0e4e7f8766cbbeb6f90831466 /dist/IO
parenta67abb3a612378541686808d03031e4055824b7d (diff)
downloadperl-f1d35e3443aa8451bf47be80983076fe28626113.tar.gz
Use the exception set in select (connect()) to early return when remote end is busy or in non existing port
For non blocking socket, it a timeout has been specified, IO::Socket internally use select(..) to detect the result of socket connection. In situation, where remote end is busy or in non-existing port, we spend entire timeout mentioned in select(..) call. We cannot completely differentiate if error is WSAECONNREFUSED(10061) or WSAETIMEDOUT(10060) in this situation. If we use the exception set in select(..) call, we can do early return and also a make a clear differentiation in error condition. This is same like what Linux handle in this situation.
Diffstat (limited to 'dist/IO')
-rw-r--r--dist/IO/lib/IO/Socket.pm19
1 files changed, 15 insertions, 4 deletions
diff --git a/dist/IO/lib/IO/Socket.pm b/dist/IO/lib/IO/Socket.pm
index 31fa18f95d..06e4e6cb62 100644
--- a/dist/IO/lib/IO/Socket.pm
+++ b/dist/IO/lib/IO/Socket.pm
@@ -118,10 +118,21 @@ sub connect {
my $sel = new IO::Select $sock;
undef $!;
- if (!$sel->can_write($timeout)) {
- $err = $! || (exists &Errno::ETIMEDOUT ? &Errno::ETIMEDOUT : 1);
- $@ = "connect: timeout";
- }
+ my($r,$w,$e) = IO::Select::select(undef,$sel,$sel,$timeout);
+ if(@$e[0]) {
+ # Windows return from select after the timeout in case of
+ # WSAECONNREFUSED(10061) if exception set is not used.
+ # This behavior is different from Linux.
+ # Using the exception
+ # set we now emulate the behavior in Linux
+ # - Karthik Rajagopalan
+ $err = $sock->getsockopt(SOL_SOCKET,SO_ERROR);
+ $@ = "connect: $err";
+ }
+ elsif(!@$w[0]) {
+ $err = $! || (exists &Errno::ETIMEDOUT ? &Errno::ETIMEDOUT : 1);
+ $@ = "connect: timeout";
+ }
elsif (!connect($sock,$addr) &&
not ($!{EISCONN} || ($! == 10022 && $^O eq 'MSWin32'))
) {