[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

TCPSocket.new blocks other threads

christoph.heindl@gmail.com

1/23/2005 4:34:00 PM

hi,

when trying to connect to an ip address, from within a thread, that
does not exist, using TCPSocket.new(ip, port), it seems that other
threads are blocked until the connection has timed out. This hangs the
entire application for about 20secs.
However i have only noticed this behaviour in windows XP (propably
others too).

Any known workarounds?

I tried to find some information on nonblocking io (sockets) with ruby,
but i gave up,
after googling for around an hour..any links would be appreciated
christoph

13 Answers

Robert Klemme

1/23/2005 6:31:00 PM

0


<christoph.heindl@gmail.com> schrieb im Newsbeitrag
news:1106498039.209351.9940@f14g2000cwb.googlegroups.com...
> hi,
>
> when trying to connect to an ip address, from within a thread, that
> does not exist, using TCPSocket.new(ip, port), it seems that other
> threads are blocked until the connection has timed out. This hangs the
> entire application for about 20secs.
> However i have only noticed this behaviour in windows XP (propably
> others too).
>
> Any known workarounds?
>
> I tried to find some information on nonblocking io (sockets) with ruby,
> but i gave up,
> after googling for around an hour..any links would be appreciated
> christoph

Just a faint hint: I remember having seen something similar some days (or
maybe weeks) ago that also involved XP. Can't remember the resolution
though. Maybe you just check with ruby-talk.

Kind regards

robert

christoph.heindl@gmail.com

1/23/2005 9:54:00 PM

0

robert,

i could not find any information in ruby-talk...
:(

christoph

martinus

1/24/2005 8:03:00 AM

0

This is a serious problem! Try this code without an internet
connection:

Thread.new {
sleep 1
TCPSocket.new("xxx.nonexisting.xxx", 1234)
}

loop {
puts "."
sleep 0.25
}

This should continuously print a ".", but after 1 second this blocks
Ruby completely.

martinus

Ville Mattila

1/24/2005 8:10:00 AM

0

"martinus" <martin.ankerl@gmail.com> writes:

> This is a serious problem! Try this code without an internet
> connection:
>
> Thread.new {
> sleep 1
> TCPSocket.new("xxx.nonexisting.xxx", 1234)
> }
>
> loop {
> puts "."
> sleep 0.25
> }
>
> This should continuously print a ".", but after 1 second this blocks
> Ruby completely.
>
Works ok with
ruby -v
ruby 1.8.2 (2005-01-23) [sparc-solaris2.8]

and

ruby -v
ruby 1.8.2 (2004-07-29) [i386-mswin32]

So this might be problem on your OS.

- Ville


Eric Hodel

1/24/2005 8:37:00 AM

0

On 24 Jan 2005, at 00:05, martinus wrote:

> This is a serious problem! Try this code without an internet
> connection:
>
> Thread.new {
> sleep 1
> TCPSocket.new("xxx.nonexisting.xxx", 1234)
^^^^^^^^^^^^^^^^^^^^^

With Thread.abort_on_exception = true

causes:

getaddrinfo: No address associated with nodename (SocketError)

after 1 second.

So this is not a TCPSocket-specific problem, but a DNS resolver
problem, probably due to your OS' DNS resolver library performing a
blocking call of some kind. There's nothing Ruby can do about this,
unless your system provides a non-blocking DNS resolver API.

Changing it to a non-local IP address with no network connection causes:

No route to host - connect(2) (Errno::EHOSTUNREACH)

after 1 second.

Adding a network connection causes it to print . until the network
connection times out on:

ruby 1.8.2 (2004-12-25) [powerpc-darwin7.7.0]

--
Eric Hodel - drbrain@segment7.net - http://se...
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04

martinus

1/24/2005 9:13:00 AM

0

Sorry, I made a mistake in my sample. This is correct:

require "socket"
Thread.abort_on_exception= true

Thread.new {
sleep 1
begin
TCPSocket.new("xxx.nonexisting.xxx", 1234)
rescue
end
puts "done"
}

loop {
puts "."
sleep 0.25
}

christoph.heindl@gmail.com

1/24/2005 9:16:00 AM

0

well actually it does work.
but try changing the from "xxx.nonexisting.xxx" to a ip address which
cannot be reached.eg 192.168.0.43

then it will block...

Artur Merke

1/24/2005 9:38:00 AM

0

christoph.heindl@gmail.com

1/24/2005 10:59:00 AM

0

thanks for your reply.
however, as i pointed out in my initial post, the problem only occurs
on windows. I searched for the problem for quite a while and it seems
that ruby uses Winsock on Windows (instead of Winsock2). Somehow ruby's
scheduler seems not to be able to schedule other threads during a
TCPSocket connection attempt. I think this is not a ruby problem in
general, but has todo with ruby + winsock.
Maybe there are any patches around?

Ville Mattila

1/24/2005 11:04:00 AM

0

"christoph.heindl@gmail.com" <christoph.heindl@gmail.com> writes:

> thanks for your reply.
> however, as i pointed out in my initial post, the problem only occurs
> on windows. I searched for the problem for quite a while and it seems
> that ruby uses Winsock on Windows (instead of Winsock2). Somehow ruby's
> scheduler seems not to be able to schedule other threads during a
> TCPSocket connection attempt. I think this is not a ruby problem in
> general, but has todo with ruby + winsock.
> Maybe there are any patches around?

Hello, works fine with me (windows 2000 + SP4 and all security patches)
....

> type foo.rb
require "socket"
Thread.abort_on_exception= true

Thread.new {
sleep 1
begin
TCPSocket.new("xxx.nonexisting.xxx", 1234)
rescue
end
puts "done"
}

loop {
puts "."
sleep 0.25
}

c:\data\ruby\bin\ruby -v foo.rb
ruby 1.8.2 (2005-01-19) [i386-mswin32]
.
.
.
.
done
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
foo.rb:16:in `sleep': Interrupt
from foo.rb:16
from foo.rb:14:in `loop'
from foo.rb:14

- Ville