Take the following code:
require ‘socket’
require ‘thread’
server = TCPServer.new(“localhost”, 0)
serv_thread = Thread.new{ server.accept }
sleep(0.1)
sock = TCPSocket.new(“localhost”, server.addr[1])
q = Queue.new
client_thread = Thread.new{
begin
sock.readline
rescue StandardError => e
q.push(e)
end
}
sleep(0.1) while client_thread.status == “run”
sock.close
client_thread.wakeup rescue nil
err = q.pop
client_thread.join
fail “Failure!” unless err.is_a?(IOError)
puts “Success!”
So, we’ve got one thread blocked on a #readline, and another thread
closes the socket out from under it. On 1.8.7-p302, this completes
successfully. On 1.9.2-p136, it hangs at q.pop.
If I uncomment the client_thread.wakeup call, both complete (although
the rescue is necessary to prevent a ThreadError on 1.8.7).
Is this expected? Which is “correct”?
Thanks,
Alex
On Thu, Feb 10, 2011 at 12:59 PM, Alex Y. [email protected]
wrote:
sleep(0.1) while client_thread.status == “run”
successfully. On 1.9.2-p136, it hangs at q.pop.
I cannot confirm this:
15:40:10 Temp$ ruby19 -v
ruby 1.9.2p136 (2010-12-25 revision 30365) [i386-cygwin]
15:40:50 Temp$ ruby19 s.rb
#<IOError: closed stream>
Success!
15:41:31 Temp$ cat s.rb
require ‘socket’
require ‘thread’
server = TCPServer.new(“localhost”, 0)
serv_thread = Thread.new{ server.accept }
sleep(0.1)
sock = TCPSocket.new(“localhost”, server.addr[1])
q = Queue.new
client_thread = Thread.new{
begin
sock.readline
q.push “OK”
rescue StandardError => e
p e
q.push(e)
end
}
sleep(0.1) while client_thread.status == “run”
sock.close
client_thread.wakeup rescue nil
err = q.pop
client_thread.join
fail “Failure!” unless err.is_a?(IOError)
puts “Success!”
15:41:36 Temp$
If I uncomment the client_thread.wakeup call, both complete (although
the rescue is necessary to prevent a ThreadError on 1.8.7).
Is this expected? Which is “correct”?
Hm… I would expect your 1.9.2 to also throw.
Btw, one thing is odd about your test case: you have two mechanisms to
synchronize threads - you read from the queue and you join
client_thread. If you really only want to track status of the thread
you could as well use Thread#value:
client_thread = Thread.new{
begin
sock.readline
nil
rescue StandardError => e
e
end
}
err = client_thread.value
Kind regards
robert
Robert K. wrote in post #980828:
On Thu, Feb 10, 2011 at 12:59 PM, Alex Y. [email protected]
wrote:
sleep(0.1) while client_thread.status == “run”
successfully. On 1.9.2-p136, it hangs at q.pop.
I cannot confirm this:
15:40:10 Temp$ ruby19 -v
ruby 1.9.2p136 (2010-12-25 revision 30365) [i386-cygwin]
$ ruby -v
ruby 1.9.2p136 (2010-12-25 revision 30365) [x86_64-linux]
is mine. Might it be an architecture issue? I don’t have a 32bit machine
handy to compare.
15:40:50 Temp$ ruby19 s.rb
#<IOError: closed stream>
Success!
15:41:31 Temp$ cat s.rb
require ‘socket’
require ‘thread’
server = TCPServer.new(“localhost”, 0)
serv_thread = Thread.new{ server.accept }
sleep(0.1)
sock = TCPSocket.new(“localhost”, server.addr[1])
q = Queue.new
client_thread = Thread.new{
begin
sock.readline
q.push “OK”
rescue StandardError => e
p e
q.push(e)
end
}
sleep(0.1) while client_thread.status == “run”
sock.close
client_thread.wakeup rescue nil
err = q.pop
client_thread.join
fail “Failure!” unless err.is_a?(IOError)
puts “Success!”
15:41:36 Temp$
If I uncomment the client_thread.wakeup call, both complete (although
the rescue is necessary to prevent a ThreadError on 1.8.7).
Is this expected? Which is “correct”?
Hm… I would expect your 1.9.2 to also throw.
That’s what I thought, but rubinius doesn’t throw either, so I wasn’t
sure.
Btw, one thing is odd about your test case: you have two mechanisms to
synchronize threads - you read from the queue and you join
client_thread.
Yes, the #join was a bit of leftover that I forgot to trim.
If you really only want to track status of the thread
you could as well use Thread#value:
client_thread = Thread.new{
begin
sock.readline
nil
rescue StandardError => e
e
end
}
err = client_thread.value
That’s a bit neater, though. I like that.
Thanks,
Alex
Alex Y. wrote in post #980861:
Robert K. wrote in post #980828:
On Thu, Feb 10, 2011 at 12:59 PM, Alex Y. [email protected]
wrote:
sleep(0.1) while client_thread.status == “run”
successfully. On 1.9.2-p136, it hangs at q.pop.
I cannot confirm this:
15:40:10 Temp$ ruby19 -v
ruby 1.9.2p136 (2010-12-25 revision 30365) [i386-cygwin]
$ ruby -v
ruby 1.9.2p136 (2010-12-25 revision 30365) [x86_64-linux]
Ok, so this also fails on i686-linux. Now, where’s the bug?
–
Alex
Robert K. wrote in post #981080:
On Fri, Feb 11, 2011 at 1:01 PM, Alex Y. [email protected]
wrote:
ruby 1.9.2p136 (2010-12-25 revision 30365) [i386-cygwin]
$ ruby -v
ruby 1.9.2p136 (2010-12-25 revision 30365) [x86_64-linux]
Ok, so this also fails on i686-linux. Now, where’s the bug?
Maybe the network stack behaves different on these different platforms.
That doesn’t explain why 1.8.7 on Linux behaves the same as cygwin
1.9.2, though.
–
Alex
On Fri, Feb 11, 2011 at 1:01 PM, Alex Y. [email protected]
wrote:
ruby 1.9.2p136 (2010-12-25 revision 30365) [i386-cygwin]
$ ruby -v
ruby 1.9.2p136 (2010-12-25 revision 30365) [x86_64-linux]
Ok, so this also fails on i686-linux. Now, where’s the bug?
Maybe the network stack behaves different on these different platforms.
Kind regards
robert
Alex Y. wrote in post #981138:
Robert K. wrote in post #981080:
On Fri, Feb 11, 2011 at 1:01 PM, Alex Y. [email protected]
wrote:
ruby 1.9.2p136 (2010-12-25 revision 30365) [i386-cygwin]
$ ruby -v
ruby 1.9.2p136 (2010-12-25 revision 30365) [x86_64-linux]
Ok, so this also fails on i686-linux. Now, where’s the bug?
Maybe the network stack behaves different on these different platforms.
That doesn’t explain why 1.8.7 on Linux behaves the same as cygwin
1.9.2, though.
Well, that was quick
http://redmine.ruby-lang.org/issues/show/4390
–
Alex
On Sat, Feb 12, 2011 at 5:06 PM, Alex Y. [email protected]
wrote:
Ok, so this also fails on i686-linux. Now, where’s the bug?
http://redmine.ruby-lang.org/issues/show/4390
Yep, Nobu is great! Thanks for filing the bug, Alex.
Cheers
robert