* backport r33007 from trunk.

* lib/net/imap.rb (idle): raises a Net::IMAP::Error when the
  connection is closed.  based on the patch by Hugo Barauna.
  [Bug #5190] [ruby-core:38930]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_3@33008 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
shugo 2011-08-19 05:18:20 +00:00
parent 31f92d788c
commit f23e93f8b3
3 changed files with 76 additions and 3 deletions

View file

@ -1,3 +1,11 @@
Fri Aug 19 14:12:57 2011 Shugo Maeda <shugo@ruby-lang.org>
* backport r33007 from trunk.
* lib/net/imap.rb (idle): raises a Net::IMAP::Error when the
connection is closed. based on the patch by Hugo Barauna.
[Bug #5190] [ruby-core:38930]
Fri Aug 19 11:28:58 2011 Shugo Maeda <shugo@ruby-lang.org> Fri Aug 19 11:28:58 2011 Shugo Maeda <shugo@ruby-lang.org>
* backport r33001 from trunk. * backport r33001 from trunk.

View file

@ -905,10 +905,15 @@ module Net
@idle_done_cond = new_cond @idle_done_cond = new_cond
@idle_done_cond.wait @idle_done_cond.wait
@idle_done_cond = nil @idle_done_cond = nil
if @receiver_thread_terminating
raise Net::IMAP::Error, "connection closed"
end
ensure ensure
remove_response_handler(response_handler) unless @receiver_thread_terminating
put_string("DONE#{CRLF}") remove_response_handler(response_handler)
response = get_tagged_response(tag, "IDLE") put_string("DONE#{CRLF}")
response = get_tagged_response(tag, "IDLE")
end
end end
end end
@ -1056,6 +1061,7 @@ module Net
rescue Exception rescue Exception
end end
} }
@receiver_thread_terminating = false
end end
def receive_responses def receive_responses
@ -1115,8 +1121,12 @@ module Net
end end
end end
synchronize do synchronize do
@receiver_thread_terminating = true
@tagged_response_arrival.broadcast @tagged_response_arrival.broadcast
@continuation_request_arrival.broadcast @continuation_request_arrival.broadcast
if @idle_done_cond
@idle_done_cond.signal
end
end end
end end

View file

@ -363,6 +363,61 @@ class IMAPTest < Test::Unit::TestCase
end end
end end
def test_connection_closed_during_idle
server = create_tcp_server
port = server.addr[1]
requests = []
sock = nil
Thread.start do
begin
sock = server.accept
sock.print("* OK test server\r\n")
requests.push(sock.gets)
sock.print("+ idling\r\n")
rescue
end
end
begin
imap = Net::IMAP.new(SERVER_ADDR, :port => port)
begin
th = Thread.current
m = Monitor.new
in_idle = false
exception_raised = false
c = m.new_cond
Thread.start do
m.synchronize do
until in_idle
c.wait(0.1)
end
end
sock.close
exception_raised = true
end
assert_raise(Net::IMAP::Error) do
imap.idle do |res|
m.synchronize do
in_idle = true
c.signal
until exception_raised
c.wait(0.1)
end
end
end
end
assert_equal(1, requests.length)
assert_equal("RUBY0001 IDLE\r\n", requests[0])
ensure
imap.disconnect if imap
end
ensure
server.close
if sock && !sock.closed?
sock.close
end
end
end
private private
def imaps_test def imaps_test