From 2bd37c71839858341cf2534657a60261e05f275f Mon Sep 17 00:00:00 2001 From: shugo Date: Fri, 19 Aug 2011 05:16:20 +0000 Subject: * 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/trunk@33007 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 6 +++++ lib/net/imap.rb | 16 +++++++++++--- test/net/imap/test_imap.rb | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1fe2bc2e2c..7641121d5d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Fri Aug 19 14:12:57 2011 Shugo Maeda + + * 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 13:18:00 2011 Kenta Murata * configure.in: defines _DARWIN_UNLIMITED_SELECT if the target_os diff --git a/lib/net/imap.rb b/lib/net/imap.rb index 9095ea399a..eacf0e4cc4 100644 --- a/lib/net/imap.rb +++ b/lib/net/imap.rb @@ -905,10 +905,15 @@ module Net @idle_done_cond = new_cond @idle_done_cond.wait @idle_done_cond = nil + if @receiver_thread_terminating + raise Net::IMAP::Error, "connection closed" + end ensure - remove_response_handler(response_handler) - put_string("DONE#{CRLF}") - response = get_tagged_response(tag, "IDLE") + unless @receiver_thread_terminating + remove_response_handler(response_handler) + put_string("DONE#{CRLF}") + response = get_tagged_response(tag, "IDLE") + end end end @@ -1056,6 +1061,7 @@ module Net rescue Exception end } + @receiver_thread_terminating = false end def receive_responses @@ -1115,8 +1121,12 @@ module Net end end synchronize do + @receiver_thread_terminating = true @tagged_response_arrival.broadcast @continuation_request_arrival.broadcast + if @idle_done_cond + @idle_done_cond.signal + end end end diff --git a/test/net/imap/test_imap.rb b/test/net/imap/test_imap.rb index 01982ab815..c67886fed4 100644 --- a/test/net/imap/test_imap.rb +++ b/test/net/imap/test_imap.rb @@ -363,6 +363,61 @@ class IMAPTest < Test::Unit::TestCase 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 def imaps_test -- cgit v1.2.3